React Hooks
Hooks are new in React 16.8. It allows you to use class component lifecycle functions and React features such as state while writing function components.
1. useState()
Basic usage
UseState () is a Hook provided by React to read and modify state. The first argument it passes in, initialState, is the initial value of state, which returns a state and the function setState that updates state. During initial rendering, the state state returned is the same value as the first parameter, initialState, passed in.
const [state, setState] = useState(initialState);
Copy the code
The setState function is used to update state. It receives a new state value and enqueues a rerendering of the component.
setState(newState);
Copy the code
Functional update
If the new state needs to be computed using the previous state, you can pass the function to setState. This function will take the previous state and return an updated value. The following counter component example shows two uses of setState:
function Counter({initialCount}) {
const [count, setCount] = useState(initialCount);
return (
<>
Count: {count}
<button onClick={()= > setCount(initialCount)}>Reset</button>
<button onClick={()= > setCount(prevCount => prevCount - 1)}>-</button>
<button onClick={()= > setCount(prevCount => prevCount + 1)}>+</button>
</>
);
}
Copy the code
The “+” and “-” buttons are functional because the updated state needs to be based on the previous state. But the reset button takes the normal form, because it always sets the count back to its initial value.
Attention!
Unlike update data in the Vue framework, useState does not automatically merge update objects. You can combine the function setState with the expansion operator to achieve the effect of merging updated objects.
setState(prevState= > {
return{... prevState, ... updatedValues}; });Copy the code
2. useEffect()
The basic concept
UseEffect () adds the ability to use a lifecycle to function components. It has the same purpose as componentDidMount, componentDidUpdate, and componentWillUnmount, but is combined into a single API.
1. The simulationcomponentDidMount
Life cycle function
useEffect(() = > {
// Mount the component and execute it
},[]);
Copy the code
2. The simulationcomponentDidUpdate
Life cycle function
const [count,setCount] = useState(1);
// Any state change will trigger
useEffect(() = > {
// Execute after any state change
});
// Specify dependent state changes to trigger
useEffect(() = > {
// Execute after the count change
},[count]);
Copy the code
3. The simulationcomponentWillUnmount
Life cycle function
const [count,setCount] = useState(1);
useEffect(() = > {
// Mount the component and execute it
return function(){
// Execute before component uninstallation}} []);Copy the code
3. useContext()
Basic usage
const value = useContext(MyContext);
Copy the code
UseContext () is used to solve the problem of child components receiving props from their grandparents and up. The code is organized in a way similar to the publish-and-subscribe pattern: the ancestral component provides the context -> child component with the value property of < myContext.provider > and gets the context through useContext(MyContext). UseContext () receives a context object (the value returned by React.createcontext) and returns the current value of that context. The value of the current context is determined by the value property of < myContext. Provider> nearest to the current component in the upper-layer component. When the latest < myContext. Provider> update is made to the component’s upper layer, the Hook will trigger a rerender, using the last context value passed to MyContext Provider.
Code sample
const themes = {
light: {
foreground: "# 000000".background: "#eeeeee"
},
dark: {
foreground: "#ffffff".background: "# 222222"}};/ / create the Context
const ThemeContext = React.createContext(themes.light);
// Specify the scope of the Context and the value of the attribute passed.
function App() {
return (
<ThemeContext.Provider value={themes.dark}>
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar(props) {
return (
<div>
<ThemedButton />
</div>
);
}
function ThemedButton() {
// Get the attribute value provided by themecontext. Provider value
const theme = useContext(ThemeContext);
return (
<button style={{ background: theme.background.color: theme.foreground}} >
I am styled by theme context!
</button>
);
}
Copy the code
4. useReducer()
The basic concept
const [state, dispatch] = useReducer(reducer, initialArg, init);
Copy the code
UseReducer () is an alternative to useState(). Compared to useState(), useReducer() passes in an extra operation on state — reducer (reducer is a function like (state, action) => newState), Returns the current state and its corresponding dispatch method.
The sample program
Here is an example of the counters in overriding useState with Reducer:
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
5. useRef()
Basic usage
const refContainer = useRef(initialValue);
Copy the code
The semantics of ref is “reference,” and we usually use ref to access DOM nodes. UseRef () returns a mutable ref object whose.current property is initialized to the passed parameter (initialValue). The returned REF object remains the same throughout the lifetime of the component.
Code sample
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () = > {
// 'current' refers to the text input element that has been mounted to the DOM
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}
Copy the code
Save the data
What is there in a component that lasts across render cycles, that is, properties that remain unchanged after the component has been rendered multiple times? The first thing that comes to mind is state. Yes, a component’s state can remain the same after multiple renderings. The problem with state, however, is that modifying it causes the component to be rerendered. UseRef can then be used to store data across the render cycle, and modifying it will not cause the component to render.
6. useMemo()
const memoizedValue = useMemo(() = > computeExpensiveValue(a, b), [a, b]);
Copy the code
Pass the “create” function and dependency array to useMemo() as arguments, and it will only recalcalculate memoized if one of the dependencies changes. This optimization helps to avoid high overhead calculations every time you render.
7. useCallback()
const memoizedCallback = useCallback(
() = > {
doSomething(a, b);
},
[a, b],
);
Copy the code
Pass the inline callback function and the array of dependencies as arguments to useCallback(), which returns the memoized callback of that callback function, which is updated only if one of the dependencies changes. UseCallback (fn, deps) equals useMemo(() => fn, deps).