This article is part of my personal wiki where I write personal notes while I am learning new technologies. You are welcome to use it for your own learning!
- HTML should be a projection of application state and not the source of truth BOOOOM!!
- Your app is a funtion of props and state
- Unidirectional data-flow. No two-way data binding.
- Easier to reason about state when it only moves in one direction.
- Two-way data binding can be unpredictable because it results cascades of changes that are hard to debug
- Inline styles (component-specific styles)
Why Use React
- Super fast (because it uses a virtual DOM)
- Component based architecture that is super composable
- Isomorphic friendly
- Just a view layer, you can include it easily into existing applications
- Simple, focused and small API
1 2 3 4 5 6 7 8 9 10 11
Why do we need a virtual DOM? What do we gain by it?
Operations with the DOM are expensive in terms of performance. A virtual DOM adds an extra layer of abstraction that allows us to update the actual DOM in the most efficient way possible, for instance, by only updating the parts that have changed, or batching changes together. Additionally, having a virtual DOM let’s React do server side rendering and even target native mobile development with React Native.
Creating a Component
1 2 3 4 5 6 7 8 9
Rendering a Component
1 2 3 4 5 6 7 8 9 10 11 12 13
State in React Components
State in react components is contained in:
- looks like HTML attributes
- it is immutable
- they let you pass data down to child components
- use only in top level component
You can define the initial state of a component in the
getInitialState function and default prop values in the
getDefaultProps function. These props will be used by a child component when the parent component doesn’t provide any values via attributes.
Component Lifecycle Methods
These methods let you hook up into a component lifecycle:
componentWillMount: runs before a component is rendered. This is a good place to set initial state
componentDidMount: runs after a component is rendered. After this we have a DOM, good spot to do stuff with the DOM, ajax requests, etc
componentWillReceiveProps: called when receiving new props (when props are changed). Not called on initial render.
shouldComponentUpdate: called before render when new props or state are being received. Not called on initial render. You can return
falsefrom this function to prevent unnecessary renderings. For instance, when a prop/state change doesn’t affect the DOM.
componentWillUpdate: runs immediately before rendering when new props or state are being received. Not called on initial render.
componentDidUpdate: runs immediately after the component is updated and rerendered.
componentWillUnmount: runs immediately after the component is removed from the DOM. Good for cleanup.
React makes it super easy to compose components together. Normally you’ll have a tree structure of components where a parent component owns a series of child component and passes data via
props into them.
A Controller View is a react component that has child components. It controls data flows for all its child components via
props. Controller views also interact with flux stores. It is recommended to have a single controller view to ensure that data updates only happen once and the render method is only called once.
Prop Validation Through
propTypes work like code contracts, that is, they let you define which
props a particular component is expecting, their types and whether they are required or not. For instance:
1 2 3 4 5 6
For the sake of improved performance,
propTypes don’t run in the production, minified version of your web app.
The de factor standard router to use in React application, React Router is a router library used and maintained by facebook. It lets you define advanced routing schemes for your single page applications in a declarative fashion:
Routeto map a url to a route
DeaultRouteto define the default route of your application (when none is given)
Redirectto redirect to an existing route
Routes and Parameterized Routes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10 11
Transitions Between Routes
willTransitionFrom methods allow you to execute code between changing routes. You can, for instance, have some authorization mechanism that checks whether or not a given user is authorized to view a route or prompt the user to save a form before leaving a particular view of your application.
willTransitionToexecutes before loading a new view
willTransitionFromexecutes before leaving the current view
1 2 3 4 5 6 7 8 9 10
Hash-based Location vs History Location
- works in all browsers
- ugly urls
- not compatible with server rendering
- History API based
- based on new HTML5 location APIs (pushState, replaceState, etc)
- doesn’t work in some legacy browsers
- nice urls
- works with server rendering
By default the react router will use hash-based location, but you can enable the history API based location using
Router.HistoryLocation like this:
1 2 3
Remember that you need to setup your server so all requests redirect to the main page. For instance, if you are using ASP.NET MVC you’ll want a catch them all rule that redirects to the root controller/action method.
Mixins are helpful to encapsulate and reuse pieces of behavior. Every react component has a
mixins property where you can specify an array of mixins that will be applied to your component. You can create your own mixins or used some of the mixins provided in React. For instance, the react router provides the
React.Navigation mixin to provide programmatic navigation functionality to any component.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
Flux comes as a response to the common MVC architecture and two way data binding which as it grows in complexity becomes harder and harder to reason about and debug. The core proposition of flux is to use a uni-directional dataflow that is much easier to reason about (data only goes in one direction) and follows these steps:
- Action: A user interacts with a react component view and this triggers an action
- Dispatcher: A dispatcher notifies any stores that have subscribed to this dispatcher about the action
- Store: They hold the application state. When a store changes as a result of an action, the react component is updated.
- View: When the user interacts with the newly rendered View a new action occurs and we’re back at
It is an unidirectional data flow because data always follows the same direction, from the action to the view, so that the view itself can never update the state of a react component directly. This results in a more strict application model where all changes are triggered by actions and therefore changes becomes easier to reason about, trace and debug.
They are triggered by a user interacting with our application and are represented via events. They can also be triggered by the server as a response to some earlier user interaction (errors, etc).
Actions are similar to a command in the command design pattern and have a type and payload (data).
The dispatcher (which is unique) receives actions and dispatches them to the different stores that are interested in a given action. All data in the application flows through the dispatcher and is routed to the stores. It basically holds a list of callbacks from the interested stores and uses them to broadcast the actions to them.
Stores hold application state, logic and data retrieval. It is not a model, it contains a model. They register themselves to be notified of the actions that interest them.
They use Node’s
EventEmitter to interact with the outside world through events. Using events they can notify react components about the application state having changed:
- They extend
- They implement a
removeChangeListenerto add/remove component subscriptions to events
- They call
emitChangeto notify subscribed components
Controller views are the top level component that manage all data flow for their children. They usually have control over the state of their child components which they share through
props and contain the logic. Additionally, the encapsulate interaction with stores.
- Super great course on react and flux on Pluralsight