Hooks API can be accessed from the React website. Learn how to implement the React Class Component using Hooks. Learn how to use Hooks to write the React Class Component. Note: Rax is written in the same way as React. This Demo is based on React

The contents of this paper are as follows: ShouldComponentUpdate: in Hooks how to get the last value of this Class Component in this The parent component obtains the dom node of the child component in which Hooks are used

How do you implement the Class Component lifecycle in Hooks

The use of Hooks to reduce the use of life cycles is currently being rephrasedby Hooks, which are currently being rephrasedby Hooks.

The Hooks lifecycle is implemented primarily with useEffect and useState, as shown in the Demo below

1.1, the constructor

The Class Component constructor function is called only once on Component instantiation and before all lifecycle function calls

UseState passing in the initialization function fn is executed only once and before Render

function useConstruct(fn) {
  useState(fn);
}
Copy the code

1.2, componentDidMount

Dependencies to an empty array are executed only once

// componentDidMount
function useDidMount(fn) {
  useEffect(fn, []);
}
Copy the code

1.3, componentDidUpdate

Dependencies do not pass values, and any render that is triggered is executed

// componentDidUpdate
function useDidUpdate(fn) {
  useEffect(fn);
}
Copy the code

1.4, componentWillUnmount

// componentWillUnmount
function useUnMount(fn) {
  useEffect(() => fn, []);
}
Copy the code

The Demo life cycle details are as follows

import React, { useState, useEffect, useRef } from 'react';

// construct
functionUseConstruct (fn) {// useState passing in the initialization function fn only executes useState(fn) once; } // componentDidMountfunctionUseDidMount (fn) {// useEffect(fn, []); } // componentDidUpdatefunctionUseDidUpdate (fn) {// Dependencies do not pass values, any render will execute useEffect(fn); } // componentWillUnmountfunction useUnMount(fn) {
  useEffect(() => fn, []);
}

function Block() {
  const [count, setCount] = useState(0);
  const instance = useRef({});

  useConstruct(() => {
    instance.current.name = 1;
    console.log('Block Component----Construct');
  });

  useDidMount(() => {
    console.log('Block Component----componentDidMount');
  });

  useDidUpdate(() => {
    console.log('instance.current.name', instance.current.name);
    console.log('Block Component----componentDidUpdate');
  });

  useUnMount(() => {
    console.log('Block Component----componentWillUnmount');
  });

  console.log('Block render');
  return (
    <div style={{backgroundColor: '#eaeaea'}} > < p > Block component < / p > < p > count: {count} < / p > < br / > < button onClick = {() = >set</button> </div>); }export default function ParentComp() {
  const [unMountBlock, setUnMountBlock] = useState(false);
  return (
    <div>
      <p>unMountBlock: {unMountBlock?'true':'false'}</p> <br /> {! unMountBlock ? <Block /> : null} <br /> <button onClick={() =>setUnMountBlock(true</button> </div>); }Copy the code

How to implement shouldComponentUpdate in Hooks

ShouldComponentUpdate useMemo shouldComponentUpdate useMemo shouldComponentUpdate useMemo shouldComponentUpdate useMemo shouldComponentUpdate useMemo shouldComponentUpdate useMemo shouldComponentUpdate Unlike Class Component, comparisons are performed outside the Component.

import React, { useState, useMemo } from 'react';

function Counter(props) {
  console.log('Counter render');
  return (
    <div>
      <p>count: {props.count}</p>
    </div>
  );
}

function Time(props) {
  console.log('Time render');
  return (
    <div>
      <p>time: {props.time}</p>
    </div>
  );
}

export default function Demo() {
  const [count, setCount] = useState(0);
  const [time, setTime] = useState(0);
  const [count2, setCount2] = useState(10); // shouldComponentUpdate // different from Class Component: Const child1 = useMemo(() => <Counter count={count} />, [count]); const child2 = useMemo(() => <Time time={time} />, [time]);return (
    <div>
      <p>count: {count}</p>
      <p>time: {time}</p>
      <p>count2: {count2}</p>
      <br />
      <button onClick={() => setCount(count + 1)}>count + 1</button>
      <br />
      <button onClick={() => setCount2(count2 + 1)}>count2 + 1</button>
      <br />
      <button onClick={() => setTime(time + 1)}>time + 1</button>
      <br />
      {child1}
      {child2}
    </div>
  );
}
Copy the code

How do I implement this in Hooks

First you need to understand that Hooks are actually still Function Component; they do not have this instances like Class Component.

By emulating the implementation using useRef, internalref.current can be thought of as the current this variable, which is used to bind related variables

import React, { useEffect, useRef } from 'react';

export default function useThis() {// internalref.current Defaults to {} const internalRef = useRef({}); // internalref.current const self = internalref.current;if (self.didMount) {
    console.log('componentDidMount', self.didMount);
  }

  useEffect(() => {
    self.didMount = true; } []);return(how to use this variable </p> </div>); }Copy the code

How do I get the last value from Hooks

UseEffect and useRef’s ability to save the last value

import React, { useState, useRef, useEffect } from 'react';

function usePrevious(value) {
  const ref = useRef();
  useEffect(() => {
    ref.current = value;
  });
  return ref.current;
}

export default function Counter() {
  const [count, setCount] = useState(0);
  const previousCount = usePrevious(count);

  return (
    <div>
      <p>count: {count}</p>
      <p>previousCount: {previousCount}</p>
      <button onClick={() => set</button> </div>); }Copy the code

How do you implement parent component calls child component methods in Hooks

As mentioned in the previous section, Hooks are still Function Component types, and cannot use refs to retrieve Component instances. Therefore, two apis are needed to implement a method in which the parent Component calls the child Component. ForwardRef and useImperativeHandle. Use useImperativeHandle in the child to export the method, wrap the component with the forwardRef, and use useRef in the parent to pass the ref to the child.

import React, { useRef, useImperativeHandle, forwardRef } from 'react'; const TextInput = forwardRef((props, ref) => { const inputRef = useRef(null); const handleFocus = () => { inputRef.current.focus(); }; UseImperativeHandle should be used with the forwardRef. UseImperativeHandle (ref, () => ({focusInput: handleFocus, hello: ()=>{} }));return (
    <div>
      <input ref={inputRef} type="text"/> <br /> <button onClick={handleFocus}> });export default function Parent() { const inputRef = useRef(null); Const handleFocus = () => {console.log(typeof findDOMNode) console.log(inputref.current) // calls child component methods inputRef.current.focusInput(); };return(<div> <TextInput ref={inputRef} /> <br /> <button onClick={handleFocus}> Parent component calls child focusInput</button> </div>); }Copy the code

Obtain the DOM node of the child component from the parent component

FindDOMNode is used to find the COMPONENT’s DOM node for related DOM processing operations.

import React, { useRef, useImperativeHandle, forwardRef } from 'react';
import {findDOMNode} from 'react-dom';

const TextInput = forwardRef((props, ref) => {
  return (
    <div ref={ref}>
      <input ref={inputRef} type="text"/> <br /> <button onClick={handleFocus}> });export default function Parent() {
  const inputRef = useRef(null);

  const handleFindDom = () => {
    const node = findDOMNode(inputRef.current);
  };

  return(<div> <TextInput ref={inputRef} /> <br /> <button onClick={handleFocus}> Parent component calls child focusInput</button> </div>); }Copy the code

In Class Component, ref can fetch Component dom as well as Component instance methods. Why do we divide this section into three and four chapters? Unfortunately, Hooks cannot implement both functions in the same ref, only in the canonical way, such as:

import React, { useRef, useImperativeHandle, forwardRef } from 'react';
import {findDOMNode} from 'react-dom'; const TextInput = forwardRef((props, ref) => { const inputRef = useRef(null); const compRef = useRef(null); const handleFocus = () => { inputRef.current.focus(); }; UseImperativeHandle (ref, () => ({focusInput: handleFocus, compRef: compRef}));return (
    <div ref={compRef}>
      <input ref={inputRef} type="text"/> <br /> <button onClick={handleFocus}> });export default function Parent() { const inputRef = useRef(null); Const handleFocus = () = > {/ / access (component const dom node node = findDOMNode (inputRef.current.com pRef. Current); console.log(node); / / call (component method inputRef. Current. FocusInput (); };return(<div> <TextInput ref={inputRef} /> <br /> <button onClick={handleFocus}> Parent component calls child focusInput</button> </div>); }Copy the code

The following is my public account, will often update JS(Node.js) knowledge and information, welcome to scan code attention exchange.