Functional component

  • A functional component, essentially a regular function, takes a parameter props and returns a reactElement
  • Return – Returns the view we want to build
  • Before React 16.7, without Hooks, functional components were very simple, they had no state or lifecycle, they were used as pure rendering components, so they were also called stateless components
import React from 'react'

export default function App() {
    return (
        <div>
            <h1>Hello React</h1>
        </div>)}Copy the code

React Hooks

  • React Hooks are officially new in React 16.8. They allow us to use state and other React functionality without having to write class components
  • It is its presence that enables functional components to replace class components

useState(initialState)

  • Using a state
  • Receives an initialization parameter
  • const [state, setstate] = useState(initialState)
    • Const [state, method for setting state] = useState(initial value)
    • You can use useState to define multiple states in the same component
    • The setState method returned by useState does not merge objects – so remember to merge the previous values below if state is a complex type
    • The setState method returned by useState is also asynchronous
function Child(props) {
    // const [count, setCount] = useState(1);
    // const [name, setName] = useState('milk');
    const [state, setState] = useState({
        name: 'milk'.count: 1
    })
    const { name, count } = state

    return (
        <div>
            <input value={name} onChange={({ target}) = >{ // setName(target.value); setState({ ... state, name: target.value }) }} /><p>{count}</p>
            <button onClick={()= >{ // setCount(count + 1); setState({ ... State, count: count + 1})}}> Incrementing</button>
        </div>)}Copy the code

UseEffect (Side effect hook)

  • Side effects: DOM, asynchrony, requests, etc
useEffect(() = > {
    // Side effect function
    return () = > {
        // The return function of the side effect function}}, [dependent parameter])Copy the code
  • Dependent parameter: executes when listening for the corresponding parameter modification or when the component is mounted
    • When no dependency parameters are written, the side effects function is executed whenever the component is updated
    • When relying on the parameter [], the side effect function is executed only after the mount
  • Mount the stage
    • Render -> Side effects function
  • Update the stage
    • Render -> return function (update soon) -> complete update (side effect function)
  • Unloading phase
    • Return function (about to unload)
import React, { useState, useEffect, Fragment } from 'react'

let upDate = false;

export default function Child(props) {
    const [count, setCount] = useState(1);
    // The parameter is []
    useEffect(() = > {
        console.log('Component mount complete');
        return () = > {
            console.log('Component about to unload');
            upDate = false;
        }
    }, [])
    useEffect(() = > {
        // The parameter is left blank or a state needs to be detected
        // Both the component mount phase and the upDate phase are triggered
        if (upDate) {
            console.log('Count update completed');
        } else {
            upDate = true;
        }
        return () = > {
            console.log('Count is about to update');
        }
    }, [count])
    return (
        <Fragment>
            <div>{count}</div>
            <p>
                <button onClick={()= >{ setCount(count + 1); }} > + 1</button>
            </p>
        </Fragment>)}Copy the code
  • useEffectIf you need to distinguish the mount/update phase, you need to use a parameter to determine this. The above use of a global variable to determine this seems to be a good solution, but it is not
  • One of the great things about components is reuse, so what about the chaos that happens when we reuse this component? We look at theuseRef

useRef

  • Remember the class componentcreateRef? HooksuseRef
  • It besidescreateRefIn addition to the function of the, there is an additional function – to record the data of the component before it is updated
    • whenuseRefWhen you store data instead of retrieving a DOM or component instance, and the source data changes, the data stored in the REF does not change and needs to be changed manually
    • After the mount phase is initialized, it won’t update as long as we don’t manually change it
    • With this feature of REF, we can pass information across the update phase of a component – get information before the component is updated
function Child(props) {
    const [count, setCount] = useState(1);

    const div = useRef(); / / get the DOM
    const upDate = useRef(count); // Get the source information
    useEffect(() = > {
        console.log(upDate);
        upDate.current = count; // You need to change it manually to update it, otherwise it will not change after initialization during mount phase
    })

    return (
        <div ref={div}>
            <p>{count}</p>
            <button onClick={()= >{ setCount(count + 1); Increasing}} ></button>
        </div>)}Copy the code

Use ref to distinguish useEffect mount/update phases

  • userefCharacteristic distinction of recordsuseEffectMount/update phase
import React, { useState, useEffect, useRef } from 'react'

export default function App(props) {
    const [count, setCount] = useState(1)
    const upDate = useRef(false);

    useEffect(() = > {
        console.log('componentDidMount');
        return () = > {
            console.log('componentWillUnmount');
        }
    }, [])
    useEffect(() = > {
        if (upDate.current) {
            console.log('componentDidUpdate');
        } else {
            upDate.current = true;
        }
        return () = > {
            console.log('componentWillUpdate'); }})return (
        <div>
            <div>{count}</div>
            <button onClick={()= > {
                setCount(count + 1)
            }}>+1</button>
        </div>)}Copy the code

Custom Hooks

  • The benefits of Hooks are simplification of component logic and ease of reusing state, most notably custom Hooks
  • It can take complex logic out and refer to it when needed, so that our components look much cleaner and have improved readability and maintainability
  • Custom hooks must be named starting with use
  • Additional hooks are available within custom hooks
  • Chestnut: Get/set scroll bar position using custom Hooks

Hooks use rules

  • You can only call Hooks in the React function
  • Use Hooks only at the top level
    • It can only be used in the outermost layer of a function – even if only to make a judgment
function App(props) {
    useEffect(() = >{});/ /)
    if (1= = =1) { useEffect(() = >{}}/ / *
    return <div></div>
}
Copy the code