Introduction of 10 kinds of Hook in React

  • 2021-12-05 05:28:38
  • OfStack

What is the directory React Hook? Hook currently available from React 1.useState 2.useEffect & useLayoutEffect 3.useMemo & useCallback 4.useRef 5.useContext 6.useReducer

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 ()= > { } } , [ ])

The first parameter is a function, which will be triggered when rendering and updating by default. By default, it comes with 1 return, and return1 functions indicate that it can deal with some things before being destroyed again The second parameter, Array "", is only executed once when it is empty, and it is not triggered when it is updated. What are the parameters inside? When the parameters change, useEffect will be executed useEffect can be used multiple times and executed in sequence The useLayoutEffect forces the execution of the useeffect to be synchronous and executes the functions inside the useLayoutEffect first

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


Related articles: