Introduction of 10 kinds of Hook in React
- 2021-12-05 05:28:38
- OfStack
What is React Hook?
React official website is introduced as follows: Hook is a new feature of React 16.8. It allows you to use state and other React features without writing class.
Completely optional You can try Hook in a few components without rewriting any existing code. But if you don't want to, you don't have to learn or use Hook now.
Hook, which is 100% backward compatible, does not contain any destructive changes.
Now available Hook has been released in v 16.8. 0.
There is no plan to remove class from React. You can read more about Hook's progressive strategy in the section at the bottom of this page.
Hook will not affect your understanding of the concept of React. On the contrary, Hook provides a more direct API for the known concepts of React: props, state, context, refs and life cycle. As we will see later, Hook also provides a more powerful way to combine them.
If you don't know enough about react, it is recommended to read the official document of react first, write demo and then read the article, because I will not elaborate on some basic things of react.
react Official Document https://zh-hans.reactjs.org/docs/hooks-state.html
React currently available Hook
hook | 用途 |
---|---|
useState | 设置和改变state,代替原来的state和setState |
useEffect | 代替原来的生命周期,componentDidMount,componentDidUpdate 和 componentWillUnmount 的合并版 |
useLayoutEffect | 与 useEffect 作用相同,但它会同步调用 effect |
useMemo | 控制组件更新条件,可根据状态变化控制方法执行,优化传值 |
useCallback | useMemo优化传值,usecallback优化传的方法,是否更新 |
useRef | 跟以前的ref,1样,只是更简洁了 |
useContext | 上下文爷孙及更深组件传值 |
useReducer | 代替原来redux里的reducer,配合useContext1起使用 |
useDebugValue | 在 React 开发者工具中显示自定义 hook 的标签,调试使用。 |
useImperativeHandle | 可以让你在使用 ref 时自定义暴露给父组件的实例值。 |
1.useState
import React from 'react';
import './App.css';
// Usual class Writing style , Change state
class App extends React.Component {
constructor(props){
super(props)
this.state = {
hook:'react hook It's really easy to use '
}
}
changehook = () => {
this.setState({
hook:' I've changed react hook Value of '
})
}
render () {
const { hook } = this.state
return(
<header className="App-header">
{hook}
<button onClick={this.changehook}>
Change hook
</button>
</header>
)
}
}
export {App}
// Functional writing , Change state
function App() {
// Created the 1 A man named hook Variables of, sethook Method can change this variable , The initial value is' react hook It's really easy to use '
const [hook, sethook] = useState("react hook It's really easy to use ");
return (
<header className="App-header">
{hook}{/** The variables and methods here can also be used directly */}
<button onClick={() => sethook(" I've changed react hook Value of ")}>
Change hook
</button>
</header>
);
}
export {App}
// Function writing of arrow function , Change state
export const App = props => {
const [hook, sethook] = useState("react hook It's really easy to use ");
return (
<header className="App-header">
{hook}
<button onClick={() => sethook(" I've changed react hook Value of ")}>
Change hook
</button>
</header>
);
};
How to use it is noted in demo above
After reading the comparison and use of useState above, a small demo has clearer structure and simpler code, which is more like writing js code. Wouldn't it be flattering to apply it to the project?
2.useEffect
&
useLayoutEffect
useEffect replaces the original lifecycle, a combined version of componentDidMount, componentDidUpdate and componentWillUnmount
useEffect( ()=
>
{ return ()=
>
{ } } , [ ])
import React, { useState, useEffect, useLayoutEffect } from 'react';
// The writing of arrow function, change the state
const UseEffect = (props) => {
// Created the 1 A man named hook Variables of, sethook Method can change this variable , The initial value is' react hook It's really easy to use '
const [ hook, sethook ] = useState('react hook It's really easy to use ');
const [ name ] = useState('baby Zhang ');
return (
<header className="UseEffect-header">
<h3>UseEffect</h3>
<Child hook={hook} name={name} />
{/** The above variables and the following methods can also be used directly */}
<button onClick={() => sethook(' I've changed react hook Value of ' + new Date().getTime())}> Change hook</button>
</header>
);
};
const Child = (props) => {
const [ newhook, setnewhook ] = useState(props.hook);
// Writing like this can replace the previous one componentDidMount , No. 2 An array with empty parameters, indicating that the useEffect Execute only 1 Times
useEffect(() => {
console.log('first componentDidMount');
}, []);
// No. 1 2 Parameters, and the array is hook, When hook When it changes, useEffect Triggers when hook In case of change, destroy it before executing the first 1 Functions.
useEffect(
() => {
setnewhook(props.hook + '222222222');
console.log('useEffect');
return () => {
console.log('componentWillUnmount ');
};
},
[ props.hook ]
);
//useLayoutEffect Mandatory useeffect The execution of is synchronous and executes first useLayoutEffect Internal function
useLayoutEffect(
() => {
console.log('useLayoutEffect');
return () => {
console.log('useLayoutEffect componentWillUnmount');
};
},
[ props.hook ]
);
return (
<div>
<p>{props.name}</p>
{newhook}
</div>
);
};
export default UseEffect;
3.useMemo
&
useCallback
They can all be used to optimize the rendering of subcomponents, or monitor the state changes of subcomponents to handle events, which is difficult to do in the past, because shouldComponentUpdate can monitor whether it changes, but can't control other external methods, and can only return true and false, while componentDidUpdate can only be executed after updating, so it is difficult to do something before rendering.
useCallback is not currently available
import React, { useState, useMemo } from 'react';
const Child = ({ age, name, children }) => {
// In use useMemo When processing, as long as the state of the parent component changes, the child component will render 1 Times, used useMemo You can listen for a status name , when name Execute when it changes useMemo Riddy 1 Functions
console.log(age, name, children, '11111111');
function namechange() {
console.log(age, name, children, '22222222');
return name + 'change';
}
{/** react Although official website useCallback And useMemo The function of is similar, but I don't know how to answer the version problem. This method can't be used at present
const memoizedCallback = useCallback(
() => {
console.log('useCallback')
},
[name],
);
console.log(memoizedCallback,'memoizedCallback')
*/}
//useMemo There are two parameters, and useEffect1 Sample, number 1 The first parameter is a function, and the first parameter is a function 2 Parameters are arrays used to monitor that a certain state does not change
const changedname = useMemo(() => namechange(), [ name ]);
return (
<div style={{ border: '1px solid' }}>
<p>children : {children}</p>
<p>name : {name}</p>
<p>changed : {changedname}</p>
<p>age : {age}</p>
</div>
);
};
const UseMemo = () => {
//useState Set the name and age, and use the 2 Two buttons change them and pass them to Child Component
const [ name, setname ] = useState('baby Zhang ');
const [ age, setage ] = useState(18);
return (
<div>
<button
onClick={() => {
setname('baby Zhang ' + new Date().getTime());
}}
>
Change one's name
</button>
<button
onClick={() => {
setage(' Age ' + new Date().getTime());
}}
>
Change one's age
</button>
<p>
UseMemo {name} : {age}
</p>
<Child age={age} name={name}>
{name} Adj. children
</Child>
</div>
);
};
export default UseMemo;
4.useRef
ref is similar to before, useRef creation-binding-use, 3 steps, look at the code and comments in detail
import React, { useState, useRef } from 'react';
const UseRef = () => {
// Here useState Bind a input, Association 1 State name
const [ name, setname ] = useState('baby Zhang ');
const refvalue = useRef(null);// Create first 1 Empty useRef
function addRef() {
refvalue.current.value = name; // Give this when you click the button ref Assignment
// refvalue.current = name // When written this way, even if ref Is not bound to the dom The value will still exist on the created ref And you can use it
console.log(refvalue.current.value);
}
return (
<div>
<input
defaultValue={name}
onChange={(e) => {
setname(e.target.value);
}}
/>
<button onClick={addRef}> Insert a name for the following </button>
<p> Give me a UseRef Name: </p>
<input ref={refvalue} />
</div>
);
};
export default UseRef;
5.useContext
The small partner who used context before will understand it. The basic usage of useContext is similar to that of context before. There are detailed annotations in the code, creating, passing values and using
import React, { useState, useContext, createContext } from 'react';
const ContextName = createContext();
// Here, for the convenience of blogging, the grandpa and grandson components are written in 1 In the files, it is normal to introduce and create one by one in the grandpa component and grandson component Context
const UseContext = () => {
// Here useState Create 1 State, and button to control the change
const [ name, setname ] = useState('baby Zhang ');
return (
<div>
<h3>UseContext Grandpa </h3>
<button
onClick={() => {
setname('baby Zhang ' + new Date().getTime());
}}
>
Change one's name
</button>
{/** Here with context Usage 1 Sample, need provider Pass to child components value Value, value No 1 It must be 1 Parameters */}}
<ContextName.Provider value={{ name: name, age: 18 }}>
{/** Subcomponents that require variables 1 It must be written in provider In the middle, sharing can be realized */}
<Child />
</ContextName.Provider>
</div>
);
};
const Child = () => {
// Create 1 Son component, which introduces grandson component
return (
<div style={{ border: '1px solid' }}>
Child Son
<ChildChild />
</div>
);
};
const ChildChild = () => {
// Create a grandchild component, accept the status of the grandchild component, and use useContext, Objects created by the Grandpa component ContextName Adj. value Value
let childname = useContext(ContextName);
return (
<div style={{ border: '1px solid' }}>
ChildChild Grandson
<p>
{childname.name}:{childname.age}
</p>
</div>
);
};
export default UseContext;
6.useReducer
usereducer here will return state and dispatch, pass them to subcomponents through context, and then directly call state or trigger reducer. We often use useReducer and useContext createContext1 to simulate the value transfer and re-assignment of reudx.
import React, { useState, useReducer, useContext, createContext } from 'react';
// Initialization stroe The type of, initialize the value, create the reducer
const ADD_COUNTER = 'ADD_COUNTER';
const initReducer = {
count: 0
};
// Normal reducer Write
function reducer(state, action) {
switch (action.type) {
case ADD_COUNTER:
return { ...state, count: state.count + 1 };
default:
return state;
}
}
const CountContext = createContext();
// Up here 1 Segment, initializing state And reducer Create context, It can be written separately 1 A file, here for the convenience of understanding, put 1 It's written in a file
const UseReducer = () => {
const [ name, setname ] = useState('baby Zhang ');
// Use in the parent component useReducer, No. 1 1 The parameters are reducer Function, first 2 The parameters are state Returns the state And dispash
const [ state, dispatch ] = useReducer(reducer, initReducer);
return (
<div>
UseReducer
{/* Pass through here context , speak reducer And state Pass to child components */}
<CountContext.Provider value={{ state, dispatch, name, setname }}>
<Child />
</CountContext.Provider>
</div>
);
};
const Child = () => {
// With normal acceptance context1 Sample, accept the value of the parent component, and trigger it by means of events, etc. reducer , implement redux Effect
const { state, dispatch, name, setname } = useContext(CountContext);
function handleclick(count) {
dispatch({ type: ADD_COUNTER, count: 17 });
setname(count % 2 == 0 ? 'babybrother' : 'baby Zhang ');
}
return (
<div>
<p>
{name} This year {state.count} Years old
</p>
<button onClick={() => handleclick(state.count)}> Grow up </button>
</div>
);
};
export default UseReducer;
Enclosed is github address 10 hook demo point 1 star, thank you!
github Address: https://github.com/babybrotherzb/React-Hook