React/Redux Flashcards
Describe how React modifies the DOM and responds to changes.
What is the Virtual DOM?
The virtual DOM (VDOM) is a programming concept where an ideal, or “virtual”, representation of a UI is kept in memory and synced with the “real” DOM by a library such as ReactDOM. This process is called reconciliation.
This approach enables the declarative API of React: You tell React what state you want the UI to be in, and it makes sure the DOM matches that state. This abstracts out the attribute manipulation, event handling, and manual DOM updating that you would otherwise have to use to build your app.
Since “virtual DOM” is more of a pattern than a specific technology, people sometimes say it to mean different things. In React world, the term “virtual DOM” is usually associated with React elements since they are the objects representing the user interface. React, however, also uses internal objects called “fibers” to hold additional information about the component tree. They may also be considered a part of “virtual DOM” implementation in React.
Is the Shadow DOM the same as the Virtual DOM?
No, they are different. The Shadow DOM is a browser technology designed primarily for scoping variables and CSS in web components. The virtual DOM is a concept implemented by libraries in JavaScript on top of browser APIs.
What is “React Fiber”?
Fiber is the new reconciliation engine in React 16. Its main goal is to enable incremental rendering of the virtual DOM. Read more.
What is virtual DOM?
The DOM stands for Document Object Model and is a tree structure in which each node is an object that represents an HTML element. As nodes of the tree are manipulated, the corresponding HTML on the webpage is changed. The DOM provides us an API to traverse and change nodes. It is accessible through document.
The virtual DOM (VDOM) is a programming concept where an ideal, or “virtual”, representation of a UI is kept in memory and synced with the “real” DOM by a library such as ReactDOM. This process is called reconciliation.
The issue and relevance to our understanding of React is that as web pages grow in size, the DOM becomes more expensive to manage and traverse. This is where the Virtual DOM comes in.
The virtual DOM is a simpler and faster abstraction of the HTML DOM. While it might be more expensive to manage two DOMs in some respects, being able to traverse and perform operations on the virtual DOM saves React from having to have costly interactions with the real one, only updating it when it absolutely needs to.
Describe React:
Declarative:
React makes it painless to create interactive UIs. Design simple views for each state in your application, and React will efficiently update and render just the right components when your data changes.
Declarative views make your code more predictable and easier to debug.
Component-based: Build encapsulated components that manage their own state, then compose them to make complex UIs.
Since component logic is written in JavaScript instead of templates, you can easily pass rich data through your app and keep state out of the DOM.
What is ReactDOM?
React elements are plain objects.
We render elements by passing in a getElemebtById(“root”) into the reactDOM.render function.
Lifecycle methods: ComponentDidMount
This function will be called only once in the whole life-cycle of a given component and it being called signalizes that the component — and all its sub-components — rendered properly.
Since this function is guaranteed to be called only once it is a perfect candidate for performing any side-effect causing operations such as AJAX requests
Here is where you load in your data.
You can’t guarantee the AJAX request won’t resolve before the component mounts. If it did, that would mean that you’d be trying to setState on an unmounted component, which not only won’t work, but React will yell at you for. Doing AJAX in componentDidMount will guarantee that there’s a component to update.
ComponentDidMount is also where you can do all the fun things you couldn’t do when there was no component to play with. Here are some examples:
draw on a element that you just rendered
initialize a masonry grid layout from a collection of elements
add event listeners
Basically, here you want to do all the setup you couldn’t do without a DOM, and start getting all the data you need.
Most Common Use Case: Starting AJAX calls to load in data for your component.
Can call setState: Yes.
Lifecycle methods: componentWillUnmount
Use this function to “clean up” after the component if it takes advantage of timers (setTimeout, setInterval), opens sockets or performs any operations we need to close / remove when no longer needed.
Here you can cancel any outgoing network requests, or remove all event listeners associated with the component.
Basically, clean up anything to do that solely involves the component in question — when it’s gone, it should be completely gone.
Can call setState: No.
Seems to clean up all the async stuff
Lifecycle methods: shouldComponentUpdate(nextProps, nextState, nextContext)
By default, all class based Components will re-render themselves whenever the props they receiver, their state or context changes. If re-rendering the component is computation heave (e.g. generating a chart) or is not recommended for some performance reasons, the developer is given access to a special function which will be called in the update cycle.
This function will be called internally with next values of props, state and object. Developer can use those to verify that the change requires a re-render or not and return false to prevent the re-rendering from happening. In other case, you are expected to return true.
shouldComponentUpdate should always return a boolean — an answer to the question, “should I re-render?” Yes, little component, you should. The default is that it always returns true.
But if you’re worried about wasted renders and other nonsense — shouldComponentUpdate is an awesome place to improve performance.
I wrote an article on using shouldComponentUpdate in this way — check it out:
But keep in mind that it can cause major problems if you set it and forget it, because your React component will not update normally. So use with caution.
Most Common Use Case: Controlling exactly when your component will re-render.
Can call setState: No.
Lifecycle methods: componentWillUpdate(nextProps, nextState)
If the shouldComponentUpdate function is not implemented, or it decided that the component should update in this render cycle, another life-cycle function will be called. This function is commonly used to perform state and props synchronization for when parts of your state are based on props.
In cases where shouldComponentUpdate is implemented, this function can be used instead of componentWillReceiveProps as it will be called only when the component will actually be re-rendered.
Similarly to all other componentWill* functions, this function might end up called multiple times before render so it it not advised to perform side-effects causing operations here.
Functionally, it’s basically the same as componentWillReceiveProps, except you are not allowed to call this.setState.
If you were using shouldComponentUpdate AND needed to do something when props change, componentWillUpdate makes sense. But it’s probably not going to give you a whole lot of additional utility.
Most Common Use Case: Used instead of componentWillReceiveProps on a component that also has shouldComponentUpdate (but no access to previous props).
Can call setState: No.
Lifecycle methods: componenetDidUpdate(prevProps, prevState, prevcontext)
This function will be called after render is finished in each of the re-render cycles. This means that you can be sure that the component and all its sub-components have properly rendered itself.
Due to the fact that this is the only function that is guaranteed to be called only once in each re-render cycle it is recommended to use this function for any side-effect causing operations. Similarly to componentWillUpdateand componentWillReceiveProps this function is called with object-maps of previous props, state and context, even if no actual change happened to those values. Because of that developers are expected to manually check if given value changed and only then perform various update operations:
Here’s why: in componentDidUpdate, you don’t know why it updated.
So if our component is receiving more props than those relevant to our canvas, we don’t want to waste time redrawing the canvas every time it updates.
That doesn’t mean componentDidUpdate isn’t useful. To go back to our masonry layout example, we want to rearrange the grid after the DOM itself updates — so we use componentDidUpdate to do so.
Most Common Use Case: Updating the DOM in response to prop or state changes.
Can call setState: Yes.
Lifecycle methods: componenetWillReceiveProps(nextProps)
This function will be called in each update life-cycle caused by changes to props (parent component re-rendering) and will be passed an object map of all the props passed, no matter if the prop value has changed or not since previous re-render phase.
This function is ideal if you have a component whose parts of state are depending on props passed from parent component as calling this.setState here will not cause an extra render call.
Please keep in mind that due to the fact that the function is called with all props, even those that did not change it is expected the developers implement a check to determine if the actual value has changed, for example:
Perhaps some data that was loaded in by a parent component’s componentDidMount finally arrived, and is being passed down.
Before our component does anything with the new props, componentWillReceiveProps is called, with the next props as the argument.
we have access to both the next props (via nextProps), and our current props (via this.props).
Here’s what we should do:
check which props will change (big caveat with componentWillReceiveProps — sometimes it’s called when nothing has changed; React just wants to check in)
If the props will change in a way that is significant, act on it
componentDidCatch(errorString, errorInfo)
A new addition in React 16 — this life-cycle method is special in way that it can react to events happening in the child component, specifically to any uncaught errors happening in any of the child components.
With this addition you can make your parent-element handle the error by — for example — setting the error info in state and returning appropriate message in its render, or logging to reporting system, e.g.:
Why use lifecycle methods?
The beauty of React is the splitting of complicated UI’s into little, bite-sized bits. Not only can we thus compartmentalize our app, we can also customize each compartment.
Through lifecycle methods, we can then control what happens when each tiny section of your UI renders, updates, thinks about re-rendering, and then disappears entirely.
componentWillMount
connecting to external API’s. For example, if you use Firebase for your app, you’ll need to get that set up as your app is first mounting.
But the key is that such configuration should be done at the highest level component of your app (the root component). That means 99% of your components should probably not use componentWillMount.
You may see people using componentWillMount to start AJAX calls to load data for your components. Don’t do this. We’ll get to that in the second.
Most Common Use Case: App configuration in your root component.
Can call setState: Don’t. Use default state instead.
Redux: The Single Immutable State Tree
We are represented the whole state of our application as a Javascript object.
All mutations and changes are explicit and they’re easily trackable in the state tree.
This is a big reason WHY we use Redux.
Redux: Describing State Changes with Actions
The state tree is read only. We cannot modify or write it.
Any time we want to change the state, we need to dispatch an action. The action is a POJO that describes the minimal representation of the data (state) in our app.
Actions need to have a type property (not undefined) - its recommended to use strings because they are serializable.
They are the middleman between the components and database. To toggle the state, we need only dispatch an action to get the desired data.