1.2.1. The react
The react component life cycle
- Mounting: The real DOM is inserted
- Updating: Being rerendered
- Unmounting: The real DOM has been removed
- Lifecycle methods include:
componentWillMount
Called before rendering, on the client side and on the server side.componentDidMount
: called after the first rendering, only on the client side. The component then generates the corresponding DOM structure, which can be accessed through this.getDomNode (). If you want to use it with other JavaScript frameworks, you can use this method to call setTimeout, setInterval, or send AJAX requests (to prevent asynchronous operations from blocking the UI).componentWillReceiveProps
Called when the component receives a new prop (after update). This method is not called when render is initialized.shouldComponentUpdate
Returns a Boolean value. Called when the component receives new props or state. Not called during initialization or when forceUpdate is used. This can be used when you are sure that you do not need to update the component.componentWillUpdate
Called when the component receives new props or state but has not yet rendered. Will not be called during initialization.componentDidUpdate
Called immediately after the component finishes updating. Will not be called during initialization.componentWillUnmount
Called immediately before the component is removed from the DOM.
What is the JSX
- JSX is a JavaScript syntax extension that looks a lot like XML.
- We don’t have to use JSX, but it has the following advantages:
- JSX executes faster because it is optimized after being compiled into JavaScript code.
- It is type-safe and errors can be found during compilation.
- Using JSX to write templates is much easier and faster.
Common hook use
- State Hook
const [state, setState] = useState(initialState);
Copy the code
UseState adds some internal state to the component by calling it in the function component. React will retain this state for repeated rendering. UseState returns a pair of values: the current state and a function that lets you update the state, which you can call in an event handler or some other place. It is similar to the this.setState of the class component, but it does not merge the new state with the old state. The only argument to useState is the initial state. If the new state needs to be computed using the previous state, you can pass the function to setState. This function takes the previous state and returns an updated value.
-
Effect Hook
useEffect
Is an Effect Hook, which adds the ability to manipulate side effects to function components. It serves the same purpose as componentDidMount, componentDidUpdate, and componentWillUnmount in the Class component, but has been consolidated into an API.- The Hook receives a function that contains imperative code that may have side effects.
- Changing the DOM, adding subscriptions, setting timers, logging, and performing other side effects within the body of a function component (in this case, during the React rendering phase) are not allowed, as this can cause unexplained bugs and break UI consistency.
- Use useEffect for side effects. The function assigned to useEffect is executed after the component is rendered to the screen. You can think of Effect as an escape route from the purely functional world of React to the imperative world.
- By default, effect will be executed at the end of each render round, but you can choose to have it executed only when certain values change.
- Typically, components uninstall with the need to clear resources such as subscriptions or timer ids created by Effect. To do this, the useEffect function returns a cleanup function.
-
UseContext: Share data across components
const value = useContext(MyContext);
- Receives a context object (the return value of React. CreateContext) and returns the current value of the context. The current context value is determined by the < MyContext.provider > value prop of the upper-layer component closest to the current component.
- When the most recent
update is made to the component’s upper layer, the Hook triggers a rerender and uses the latest context value passed to MyContext Provider. Even if the ancestor uses React. Memo or shouldComponentUpdate, it will be rerendered when the component itself uses useContext.
- Remember that the argument to useContext must be the context object itself:
- Correct:
useContext(MyContext)
- Correct:
- Components that call useContext are always rerendered when the context value changes.
-
useReducer
const [state, dispatch] = useReducer(reducer, initialArg, init);
useState
Is an alternative to. It receives a Reducer of the form (state, action) => newState and returns the current state and its accompanying dispatch method.
const initialState = {count: 0}; function reducer(state, action) { switch (action.type) { case 'increment': return {count: state.count + 1}; case 'decrement': return {count: state.count - 1}; default: throw new Error(); } } function Counter() { const [state, dispatch] = useReducer(reducer, initialState); return ( <> Count: {state.count} <button onClick={()= > dispatch({type: 'decrement'})}>-</button> <button onClick={()= > dispatch({type: 'increment'})}>+</button> </> ); } Copy the code
-
UseCallback: Performance optimization
-
// useCallback(callback, [dependent value]) const memoizedCallback = useCallback( () = > { doSomething(a, b); }, [a, b], ); Copy the code
- Returns a memoized (cache) function, in relying on the same case, multiple definitions, the return value is the same, his principle is calling a function for the first time when using a set of parameters, will cache parameters and calculation results, when using the same parameter to invoke the function again, will return to the corresponding cache the results directly.
useCallback(fn, deps)
The equivalent ofuseMemo(() => fn, deps)
-
-
UseMemo: Performance optimization
-
const memoizedValue = useMemo(() = > computeExpensiveValue(a, b), [a, b]); Copy the code
- Returns an memoized value.
- You pass in the create function and the dependency array as arguments to useMemo, which recalculates memoized values only when a dependency changes. This optimization helps avoid costly calculations every time you render.
- Remember that functions passed into useMemo are executed during rendering. Please do not perform non-rendering operations inside this function. Operations such as side effects are used by useEffect, not useMemo.
- If the dependency array is not provided, useMemo evaluates the new value each time it renders.
- You can use useMemo as a means of performance optimization, but don’t use it as a semantic guarantee. In the future, React might choose to “forget” some of the previous Memoized values and recalculate them at the next rendering, such as freeing memory for off-screen components. Write code that can run without useMemo first — then add useMemo to your code to optimize performance
-
-
useRef
const refContainer = useRef(initialValue);
useRef
Return a mutable ref object whose.current property is initialized as the passed parameter (initialValue). The ref object returned remains constant throughout the life of the component- In essence,
useRef
Like a “box” that can hold a mutable value in its.current property
-
useImperativeHandle
useImperativeHandle(ref, createHandle, [deps])
- UseImperativeHandle allows you to customize the instance value exposed to the parent component when using a ref. In most cases, imperative code like ref should be avoided. UseImperativeHandle should be used together with the forwardRef
-
useLayoutEffect
- Its function signature is the same as useEffect, but it calls Effect synchronously after all DOM changes. You can use it to read DOM layouts and trigger rerenders synchronously. The update schedule inside useLayoutEffect is refreshed synchronously before the browser performs the drawing.
The condition triggered by the Render method
Three ways:
- Through the setState
- this.forceUpdate()
- Through state management, such as Mobx, Redux, etc
- Initialize the
- The render function is called once when the component is first loaded
- update
- State changes
- Changes to props
- Forced to update
- If not the first two and you want the component to update, you can use
this.forceUpdate()
- If not the first two and you want the component to update, you can use
React’s synthetic event system
SyntheticEvent
The instance will be passed to your event handler, which is a cross-browser wrapper for the browser’s native event. In addition to being compatible with all browsers, it has the same interface as browser native events, including stopPropagation() and preventDefault().- If for some reason you need to use the browser’s low-level events, only use them
nativeEvent
Property. eachSyntheticEvent
Objects contain the following propertiesboolean bubbles boolean cancelable DOMEventTarget currentTarget boolean defaultPrevented number eventPhase boolean isTrusted DOMEvent nativeEvent void preventDefault() boolean isDefaultPrevented() void stopPropagation() boolean isPropagationStopped() void persist() DOMEventTarget target number timeStamp string type Copy the code
What is High-level component Hoc
- HOC is an advanced technique used in React to reuse component logic. HOC itself is not part of the React API; it is a design pattern based on the composite features of React.
- Specifically, a higher-order component is a function that takes a component and returns a new component
const EnhancedComponent = higherOrderComponent(WrappedComponent);
- HOC is common in third-party libraries for React, such as Redux’s Connect and Relay’s createFragmentContainer.
The key role
- React’s key property is a special property. It is not for developers, but for react itself. With the key property, react establishes a corresponding relationship with components. It’s like everyone has an ID card to identify them. React considers the same key to be the same component. In this way, components corresponding to the same key will not be created later
Context usage and usage scenarios
- Context provides a way to pass data across the component tree without manually adding props for each layer of components.
// Context allows us to pass values deep into the component tree without explicitly traversing each component.
// Create a context for the current theme (" light "is the default).
const ThemeContext = React.createContext('light');
class App extends React.Component {
render() {
// Use a Provider to pass the current theme to the following component tree.
// Any component, no matter how deep, can read this value.
// In this case, we pass "dark" as the current value.
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>); }}// Intermediate components no longer have to specify the theme to pass down.
function Toolbar() {
return (
<div>
<ThemedButton />
</div>
);
}
class ThemedButton extends React.Component {
// Specify contextType to read the current theme context.
// React will find the nearest theme Provider and use its value.
// In this case, the current theme value is "dark".
static contextType = ThemeContext;
render() {
return <Button theme={this.context} />; }}Copy the code
- Context is mainly used when many components at different levels need to access the same data. Use caution because this makes components less reusable.
- Component composition is sometimes a better solution than context if you just want to avoid passing properties through layers.
Error Boundaries usage and usage scenarios
- The error boundary is a React component that catches and prints JavaScript errors that occur anywhere in its child tree, and instead of rendering the broken child tree, it renders the alternate UI. Error bounds catch errors during rendering, in lifecycle methods, and in constructors throughout the component tree
- Note that error boundaries do not capture errors in the following scenarios:
- Event Handling (learn more)
- Asynchronous code (such as setTimeout or requestAnimationFrame callback)
- Server side rendering
- Errors thrown by itself (not by its children)
- Error boundaries work like JavaScript’s Catch {}, except that they only apply to React components. Only class components can be error bound components. In most cases, you only need to declare the error boundary component once and use it throughout the application.