Hook profile

Hook is a new feature in React 16.8. It lets you use state and other React features without having to write a class.

State Hook

import React, { Component } from 'react'
function Demo(){
    // Declare a state variable called "count"
    const [count,setCount] = React.useState(0)
    function add(){
        setCount(count+1)   SetCount (count => count+1)
    }
    return (
        <div>
            <h1>The current count value is: {count}</h1>
            <button onClick={add}>I add 1 point</button>
        </div>)}Copy the code

Effect Hook

UseEffect Hook can be regarded as a combination of componentDidMount, componentDidUpdate and componentWillUnmount.

import React, { Component } from 'react'
function Demo(){
    const [count,setCount] = React.useState(0)
    UseEffect can be used in function components to emulate life hooks in class components
    React.useEffect(() = >{
        let timer = setInterval(() = > {
            setCount(count= >count+1)  // componentDidmount componentDidUpdate
        }, 1000);
        return () = >{
            clearInterval(timer)   // Remove timer in componentWillUnmount
        }
    },[count]) 
    function add(){
        setCount(count= >count+1)}function unmount(){
        ReactDOM.unmountComponentAtNode(document.getElementById('root'))}return (
        <div>
           <h1>The current count value is: {count}</h1>
           <button onClick={add}>Click on add 1</button>
           <button onClick={unmount}>Click uninstall component</button>
        </div>)}Copy the code

UseEffect (() => {return () => {}}, []); In the code above, [count] stands for check count. The callback is executed after each change in count. If the second parameter is omitted, all variables are tested.

Ref Hook

React.createref () in a similar class component

function Demo(){
    const myRef = React.useRef()  / / create
    function show(){
       / / use
       alert(myRef.current.value)
    }
    return (
        <div>Binding * /} {/ *<input type="text" ref={myRef}/>   
            <button onClick={show}>Click on my prompt data</button>
        </div>)}Copy the code

SetState Specifies the method of updating the status

import React, { Component } from 'react'
class Demo extends Component {
    state = {count:0}
    add = () = >{
        const {count} = this.state
        //setState(stateChange, [callback])
        // Callback is an optional function called after status updates and interface updates
        //1. Object form
        // this.setState({count:count+1},()=>{
        // console.log(this.state.count)
        // })

        //2
        this.setState((state,props) = >{
            return {count:state.count+1}})}render(){
        return (
            <div>
                <h1>The current sum is: {this.state.count}</h1>
                <button onClick={this.add}>I add 1 point</button>
            </div>)}}Copy the code

Fragment

A common pattern in React is for a component to return multiple elements. Fragments allow you to group sublists without adding additional nodes to the DOM.

function Demo(){
    // The document Fragment replaces the outer div Fragment with only one key attribute
    const {Fragment} = React
    return (
        <Fragment>
            <h1>Fragment...</h1>
        </Fragment>)}Copy the code

Context

A method of communication between components, often used for communication between ancestor components and descendant components

const Context = React.createContext() 
const {Provider,Consumer} = Context
function DemoOne(){
    const [name] = React.useState('sandwich')
    return (
        <div>
            <Provider value={name}>
                <DemoTwo />
            </Provider>                   
        </div>)}function DemoTwo(){
        // The first method applies only to class components
        //static contextType = Context
        //this.context reads the value of the context
     return (
         <div>{/* Second way, general */}<Consumer>
                {
                    value => <h3>----DemoOne: {value}</h3>
                }
            </Consumer>
        </div>)}Copy the code

Component optimization

Component 2 problems

  • As long as the executionsetState()Even if the state data is not changed, the component is re-createdrender()
  • As soon as the current parent component rerenders (), it automatically rerenders the child components, which is inefficient

Reason: shouldComponentUpdate() in Component always returns true

Solutions:

  1. Override the shouldComponentUpdate() method to compare the old and new state or props data, returning true if there is any change, and false if there is no change
  2. With PureComponent, the PureComponent overrides shouldComponentUpdate(), which returns true only if the state or props data changes
class Parent extends React.PureComponent {
    state = {count:1}
    test = () = >{
        this.setState({})  // Just call setState, it doesn't change any state
    }
    render(){
        console.log('parent-render')  // Output once
        return (
            <div>
                <h1>Parent</h1>
                <button onClick={this.test}>Click on the button</button>
                <Child/>
            </div>)}}class Child extends React.PureComponent {
    render(){
        console.log('child-render')   // Output once
        return (
            <div>Child</div>)}}Copy the code

Render Props

A component with Render Prop takes a function that returns the React element and implements its own rendering logic within the component by calling this function.

   // Similar to component slots in Vue
class Parent extends React.Component {
   render(){
       return (
        <div>
           <A render={data= ><B data={data}></B>} ></A>
        </div>)}}class A extends React.Component {
    state={test:'The data A needs to pass to B'}
    render(){
       const {test} = this.state
       return(
        <div>} {this.props. Render (test)} {function.props. Render (test)}</div>)}}class B extends React.Component{
    render(){
        return (
            <div>{/* Receive data from A */}<h3>{this.props.data}</h3>
        </div>)}}Copy the code

Error boundary

Used to catch descendant component errors and render alternate pages

Usage: getDerivedStateFromError with componentDidCatch

Features: Error bounds are used when descendant components can only catch errors generated during the life cycle of descendant components, not errors generated by their own components and errors generated by other components in composite events and timers.

class Parent extends React.Component {
    state={
        hasError:' '   // Used to identify whether a child component has an error
    }
    // This hook is called when an error occurs in a child of Parent
    static getDerivedStateFromError(error){
        console.log('Child component error')
        return {hasError:error}
    }
    componentDidCatch(){
        console.log('Error while rendering component notifying coder of bug')}render(){
        return (
            <div>
                {this.state.hasError ? <h2>The current network is unstable. Please try again later</h2> : <Child/>}
            </div>)}}class Child extends React.Component {
    state = { users:' '}
    render(){
        const {users} = this.state
        return (
            <div>
                {
                    users.map((item)=>{
                        return <li key={item.id}>{item.id}---{item.name}</li>})}</div>)}}Copy the code

Users is a null character, and traversing users in Child will result in an error. Using an error boundary will not crash the entire page.