If you go declarative, you have composability.
Basically treat the app as a game engine, and use a lot of the same techniques.
You can easily build completely isolated, reusable, and composable UI components. Nested views just become a natural extension of the way React works.
UI are fundamentally tree. Dealing with REST endpoint introduces complexity. Whatever comes out from that endpoint is typically not in the shape my UI expected.
UI components should define what they need. Use a recursive description (JSON, EDN, Transit, etc). Falcor, JSON Graph.
Any Cycle.js app can be reused as a component in a larger Cycle.js app.
Cycle.js treat every component as a mini-program of its own. We should also do that in React. Every React component we built, we should treat it as our main() program!
Remember, components in React are pretty much like functions, you can spit a function into many and compose or combine in any way you want.
By having taken the data out and put all actions elsewhere, your components should be pure function to take in props and render HTML output. That's it!
- Composable components
- A Modular Approach to UI Problem Solving
- React reconciliation
- React Components, Elements, and Instances
- React Elements vs React Components
- React (Virtual) DOM Terminology
- Component Brick and Mortar
- JavaScript Application Architecture on the road to 2015
- Component is what you should be doing now for modern UI
- Building React plugins
- Composition
- Some component example from Eric Elliott
- Coding with React like a Game Developer
- Truly encapsulated React components?? Avoid classes?
- Many ways to write React component without using ES6 classes
- react-class
- Best example of distributed component: react-soundplayer
- End-to-end hypermedia
- How to write a React Component
- Controller View Pattern
- Autobind using core-js
- Experimenting with higher-order components in React
- Interacting with the DOM
- Recompose - A microcomponentization toolkit for React
// This is a quick component in file Note.jsx
import React from 'react'
export default () => <div>A very simple component</div>
// To use
<Note />
// Essentially it is just returning a React Element
export default function() {
return <div>A very simple component</div>;
};A good rule of thumb in React is that everything that can be expressed as a component, should be. Think React-Router and DragDropContext wrapping - Component vs Mixin
// FluxComponent is the wrapper component
render() {
<div>
<SiteNavigation />
<MainContentArea>
<FluxComponent connectToStores={{}}>
<BlogPost />
</FluxComponent>
</MainContentArea>
<SiteSidebar />
<SiteFooter />
</div>
}Try passing in components to other components if you have similar components that have slightly different displays. Or you can use this.props.children and put it inside.
Components are just state machines. React thinks of UIs as simple state machines. By thinking of a UI as being in various states and rendering those states, it's easy to keep your UI consistent.
DOM is stateful. Input focus and selection, scroll position, etc.
Unintentional side effects are the bane of code reuse. They occur when multiple functions depend on and manipulate the values of the same variables or object properties. In this situation, it becomes much more difficult to refactor code, because your functions assume too much about the state of the program.
Remember that components don't have to emit DOM. They only need to provide composition boundaries between UI concerns. - See Smart and Dumb components
A state machine always have initial state as model by getInitialState.
Do not use platform components, always use <PrimaryButton> instead of plain platform <button> component. For iOS, don't use <View>, use your own abstracted components.
For EVA mistake, the <Editor> is too heavy and we did not break it down into even smaller components. The <Editor> itself is the DnD container which should not be the case. Whenever there is a drag event, the whole <Editor> will be affected and the <AddPreview> will be unnecessarily wasted in its rendering effort.
Always break your component down into single responsibility! And break it down further after that!
- Components are just views, don't place business logic in it. For example, in a Todo app, if a button creates a Todo item for each click event, you are doing it wrong. A better way is to ship that code off to another object or Action. Searching through components to determine behaviour is not really something we should be doing anyway.
- A component shouldn't worry about networking.
- Composable. Self-contained and stateless. In order to be self-contained, the component cannot rely on any other specific components. But of course it can be and must "composed" of other components.
- Component should be stateless. Most components should not maintain its own state. Instead it should defer state-management to a parent container sometimes called container components.
- Container components should not have any styling! Leave it to the presentation components.
- Don't be clever and pass a giant object which is consumed by a child component.
- Don't pass in whole collection object, pass in the
fetchmethod as prop and call that prop withincomponentWillMountinstead. Then you can do spinner at that component instead of knowing when to spin from the parent.
Remember, components don't have to emit DOM. They only need to provide composition boundaries between UI concerns.
How small should a component be? Take a look at this:
const LatestPostsComponent = props => (
<section>
<h1>Latest posts</h1>
{ props.posts.map(post => <PostPreview key={post.slug} post={post} />) }
</section>
);My biggest pet peeve is it is harder to compose, reuse, nest, and generally move around container components because there are two independent hierarchies at the same time (views and reducers). It is also not entirely clear how to write reusable components that either use Redux as implementation detail or want to provide Redux-friendly interface. (There are different approaches.) I’m also not impressed about every action having to go “all the way” upwards instead of short-circuiting somewhere. In other words, I would like to see something like React local state model but backed by reducers, and I would like it to be highly practical and tuned to real use cases rather than a beautiful abstraction. - Issue#1385
You will often hear React developers refer to controller views - a React component that typically sits at or near the top of a section of the page, which listens to one or more stores for changes in their state. As stores emit change events, the controller view updates with the new state and passes changes down to its children via props.
Controller view must be capable of:
- Publishing actions
- Listening to stores
Creating a good container components will take you awhile to really get the hang of.
If different parts of your app require fetching a model, create one container component for fetching data, then pass that state down into any number of different presentation components. From there, handle any interactions your user might cause.
Container component separates data-fetching and rendering concerns. Or components can't be concerned with both presentation and data-fetching.
If you decide to split your components into Data Component and Presentational Component, you might as well write functional stateless components.
- Understanding the React Component Lifecycle
- React component's lifecycle
- React In-depth Book - The React Life Cycle
componentWillMount and componentDidMount will get called whenever state or props changed, so if you only want to respond to state change, you need to use the callback at this.setState({}, callback).
defaultProps
Invoked once, both on the client and server, immediately before the initial rendering occurs.
It's important to note that calling this.setState within this method will not trigger a re-render. So , don't do any data fetching here.
Do not call this.setState here
Invoked only on the client! Great for setting up interval.
Warning: Be careful that once it has mounted and if the props is going to change, this lifecycle methods won't be invoked again, please see componentWillReceiveProps
componentDidMount() {
this.interval = setInterval(this.tick, 1000);
}
componentWillUnmount() {
clearInterval(this.interval);
}Use this to react to props transition before render() is called. Calling this.setState will not trigger an additional re-render and we can access old props via this.props.
Call immediately before rendering. Great for triggering animation. You cannot use this.setState() here!
componentWillUpdate(nextProps, nextState) {
if (nextProps.visibility) {
$(??).velocity('slideFadeIn');
} else {
$(??).velocity('reverse');
}
}Do not call this.setState here
Happens every time the element is re-rendered. Good for maintaining scroll position. You can do paranoid validation here also, but admittedly is not needed (like text length limiting)
Also good when you need to update 3rd-party JavaScript library like Select2/Chosen.
componentDidUpdate() {
var node = this.getDOMNode();
node.scrollTop = node.scrollHeight;
}
// Limiting the text should really be done at event handler, but
// here we are just being paranoid and do additional validation
componentDidUpdate(prevProps, prevState) {
if (this.state.text.length > 3) {
this.replaceState(prevState);
}
}// Good for doing input focus
componentDidUpdate(prevPros) {
const value = this.props.value;
const prevValue = prevProps.value;
if (this.isMounted && value.errors && value.errors != prevValue.errors) {
if (value.errors.email) {
this.refs.email.focus();
}
}
}Child component receive immutable properties from their parent. Such an relationship is called ownership. Components that set props of other components are owners but not necessarily direct parents in terms of DOM structure. This is one-way data flow.
It is important to draw a distinction between ownership and parent-child relationship.
Think of React as a snapshot in time, not "over" time. You only think of the "now".
rendershould be idempotentrendershould not cause side-effects.rendermust be pure, meaning it does not change the state or modify the DOM output.- You can return
nullorfalseif you do not want to render anything at all.
You must remember that the result returned from render() is not the actual DOM or any action being taking place. If you have a console.log() in your render(), it will be printed on the console, but do not make the mistake of thinking that your render() has been completed, it has not! The returned virtual DOM is just sitting there waiting for its chance to truly render on the screen for the next available clock tick (RAF). While waiting for the next clock tick, React will diff the virtual DOM to determine if it even need to update the real DOM or not.
- React Pure Render Performance Anti-Pattern
- react-pure-render
- A quick look at rendering whitespace using JSX
- Is render() being called too many times?
It is generally recommended that you funnel all your complex processing through the render() method. Event handlers just setState() while render() is the hub for all of your core logic.
Decide everything in the render() functions. This means all calculations and conditionals! Make use of helper functions if you can like renderFullName() etc. Of course for CPU intensive calculations, use memoization function.
var memoize = require('lodash.memoize');Data binding is a hack around re-rendering.
When Parent need to re-render, it will also automatically re-render any Child. This is the most basic functionality of React re-rendering logic.
When
setStateis called, the component rebuilds the virtual DOM for its children. If you callsetStateon the root element, then the entire React app is re-rendered. All the components, even if they didn't change, will have their render method called. This may sound scary and inefficient but in practice, this works fine because we're not touching the actual DOM.Another important point is that when writing React code, you usually don't call
setStateon the root node every time something changes. You call it on the component that received the change event or couple of components above. You very rarely go all the way to the top. This means that changes are localized to where the user interacts
If you do not want Children to be re-render, you have to use Immutable and compare props at shouldComponentUpdate.
Note: forceUpdate skip shouldComponentUpdate, essentially a full hard refresh.
Once again:
When each component re-renders the children it renders re-render too (unless prevented by shouldComponentUpdate).
Re-rendering on every change is impractical unless all your component have very strict shouldComponentUpdate implementations like those provided by Om.
Note: PureRender/shouldComponentUpdate really is considered an escape hatch for performance and is not necessarily something that should be blindly applied to every component.
See http://davidtheclark.com/modular-approach-to-interface-components/ for a nice way to modularize other libraries.
- React Widget
- Strand
- React Components
- React Parts
- React Rocks
- UI Components
- Build your own component libraries
- react-component
- React Toolbox with Material Design
- classie
- React Rocks - A list of useful components
- Elemental UI
- TouchstoneJS
- Nuka Carousel
- React DnD
- React HotKeys
- react-aria-menubutton
- Griddle - Data Table
- FixedDataTable
- react-quill - Editor
- react-select
- react-waypoint - Infinite Scrolling
- See also here for more react-waypoint
- Autocomplete example
- react-markdown
- react-tags
- react-icons
- react-web-sdk
- react-onclickoutside
- react-list-view
- react-text-filter
- react-popup
- react-springs
- react-autocomplete
- react-pikaday
- react-select-search
- react-avatr
- react-absolute-grid
- instatype - Simple React Typeahead
- react-mentions
- react-ux-password-field - Using zxcvbn
- react-soundplayer
- Amazing constraint-base grid system
- Spectacle - Presentation with good PDF support
- sliding-window
- react-nexus
- react-popups
- react-contextmenu
- cpr-select
- react-sparklines
- react-progress-button
- react-table-sorter
- react-ui-tree
- react-object-inspector
- react-render-visualizer
- react-tunnel
- react-inline-grid
- trello-react
- react-hammerjs
- react-selectize
- react-joyride
- react-text-trail
- react-autosuggest
- Chosen
- react-data-grid
- react-list - Infinite scroll
- react-input-slider
- react-rangeslider
- react-fa - Can study it
- react-matchmedia-connect
- React-Spreadsheet-Component
- react-xhr-uploader
- react-infinite
- react-notification
- react-tabs
- react-tab-panel
- react-swipe-views
- kendo-react-inputs
- simple-react-button
- react-hoverbox
- react-autosuggest
- Uber - react-map-gl
- react-day-picker
- react-date-picker
- A very nice time picker
- Task Calendar
- hv-react-calendar
- rc-calendar
- DZDateTimePicker
Just use Victory.js for new project.
- react-vis from Uber
- Victory.js
- Recharts = React + Charts
- d-Threeact
- Integrating D3.js visualizations in a React app
- Scalable Data Visualization
- react-d3
- D3 with React.js
- d3-react-squared
- React and D3 Part 1: Layout
- Pyxley: Python Powered Dashboards
- On D3, React, and a little bit of Flux
- Visualizing data in React.js
- Building D3-inspired charts with React
- D3 with React the right way
- D3 and React - the future of charting components?
- D3 for math + ReactJS for rendering
import React, { Component } from 'react';
import d3 from 'd3';
export default class Sparkline extends Component {
render() {
const { width, data, height, interpolation } = this.props;
const x = d3.scale.linear()
.range([0, width])
.domain(d3.extent(data, (d, i) => i))
const y = d3.scale.linear()
.range([height, 0])
.domain([0, 100])
const line = d3.svg.line()
.x((d, i) => x(i))
.y((d) => y(d))
.interpolate(interpolation)
return (
<svg className="sparkline" width={width} height={height}>
<path d={line(data)} />
</svg>
);
}
}Q: Curious why string refs look to be deprecated in a future version of React. Is it simply that callbacks can already handle basic references / are more versatile? Subtle way to discourage the use of ref's as an escape hatch for component communication? - BradColthurst
A: not to discourage people, though that could be a nice side-effect? a handful of reasons reasons: (1) string refs make it less clear that there's a timing aspect involved and that the ref only becomes available at a certain point in the mount cycle, whereas function refs make it a little clearer, (2) function refs are more flexible and you could read some property from or call a method on the node without storing it, (3) if you have a helper function outside your class that returns a component with a string ref, it's unclear where that ref will be attached, and (4) we track which component is the "owner" to attach refs to using a stateful module within the 'react' package, which is intellectually gross but can also complicate things in a practical sense and means you it's harder to use multiple versions of the 'react' package (which should otherwise work correctly)
https://github.com/reactiflux/q-and-a/blob/master/ben-alpert_react-core.md
var Datepicker = React.createClass({
render() {
return React.createElement('input', {type: 'text'});
}
runJQ() {
$(React.findDOMNode(this)).datepicker(this.props);
}
componentDidMount() {
this.runJQ();
}
componentDidUpdate(prevProps) {
if (!propsEqual(this.props, prevProps)) {
this.runJQ();
}
}
});$.fn.react = function(component, props) {
React.render(
React.createElement(component, props),
this.get(0)
);
};
$('body').react(TodoList, {items: ['Get milk']});class link { // No need extends?
render() {
var className = this.props.highlighted ? 'highlight' : '';
var children = this.props.children;
return (
<a
className={'link-button ' + className}
href={this.props.href}
rel="prefetch">
{children}
</a>
);
}
}
// Use it as
<Link highlighted />