useEffect

His conclusion

useReducer

When multiple states need to be updated together, you should consider using useReducer to improve application performance

Using useReducer can reduce the use of useState, reduce the number of render times of VDOM, and facilitate unified management of multiple variables

For example, the login page, multiple states, login success to set a lot of states, login failure to set a lot of login page examples

You can also delay creating the initial state. To do this, you can pass the init function as the third argument. The initial state will be set to init(initialArg). The third argument is the function, delay processing

UseMomo and usecallback

Using usecallback

The memo does not seem to be working when the parent passes state to the child, so we need to introduce hooks useCallback and useMemo.

Interface ChildProps {name: string; onClick: Function; } const Child = ({name, onClick}: ChildProps): jsx.Element => {console.log(' Child? ') return(<> <div> I am a child component, and the parent sends the data: {name}</div> <button onClick={onclick. bind(null, 'new subcomponent name')}> Change name</button> </>); } const ChildMemo = memo(Child); const Page = (props) => { const [count, setCount] = useState(0); Const [name, setName] = useState('Child component '); Return (<> <button onClick={(e) => {setCount(count+1)}}> add 1</button> <p>count:{count}</p> <ChildMemo name={name} onClick={(newName: string) => setName(newName)}/> </> ) }Copy the code

When the parent calls the child, add useCallback to the onClick parameter [], and it will not change after the first initialization.

<> <button onClick={(e) => {setCount(count+1)}}> </button> <p>count:{count}</p> <ChildMemo name={name} onClick={ useCallback((newName: string) => setName(newName), []) }/> {/* useCallback((newName: String) => setName(newName),[]) */} {/* This uses useCallback to optimize the function passed to the child component, only initialize this function once, no new function is generated next time </>Copy the code

Using usememo

interface ChildProps { name: { name: string; color: string }; onClick: Function; } const Child = ({name, onClick}: ChildProps): jsx.Element => {console.log(' Child? ') return( <> <div style={{ color: Name. Color}}> I am a child of the component, the parent of the data: {name}</div> <button onClick={onclick. bind(null, 'new subcomponent name')}> Change name</button> </>); } const ChildMemo = memo(Child); const Page = (props) => { const [count, setCount] = useState(0); Const [name, setName] = useState('Child component '); Return (< > < button onClick = {(e) = > {setCount (count + 1)}} > 1 < / button > < p > count: {count} < / p > < ChildMemo name = {{name, color: name.indexOf('name') ! = = 1? 'red' : 'green'}} onClick={ useCallback((newName: string) => setName(newName), []) } /> </> ) }Copy the code

Update attribute name is the object type, then the child component is still the same execution, when the parent component updates other states, the child component’s name object property will always be re-rendering changes, resulting in constant execution, which is also an unnecessary waste of performance. To solve this problem, use the name parameter to use useMemo, depending on changes in the state.name data

<ChildMemo // Use useMemo to return the same object. The second argument is a dependency. A new object is created when the name changes. name.indexOf('name') ! = = 1? 'red' : 'green' }), [name]) } onClick={ useCallback((newName: string) => setName(newName), []) } {/* useCallback((newName: String) => setName(newName),[]) */} {/* This uses useCallback to optimize the function passed to the child component, only initialize this function once, no new function is generated next time />Copy the code

conclusion

In cases where the child component does not need the values and functions of the parent component, you simply wrap the child component with the Memo function. In the case of functions, you need to consider whether any function is passed to the child component using useCallback. Use useMemo when values are dependent on items that are equivalent to objects and arrays (do not use useMemo when returning primitive data types such as strings, numbers, and Booleans). Don’t blindly use these hooks

react.createcontext

References cannot use function components, only class components

You must use the component reference first, otherwise you get an empty objectOr you could do it this way

Function components can be consumed

It is best to use useContext for consumption

import React, { useContext } from "react";
import ReactDOM from "react-dom";

const TestContext= React.createContext({});

const Navbar = () => {
  const { username } = useContext(TestContext)

  return (
    <div className="navbar">
      <p>{username}</p>
    </div>
  )
}

const Messages = () => {
  const { username } = useContext(TestContext)

  return (
    <div className="messages">
      <p>1 message for {username}</p>
    </div>
  )
}

function App() {
  return (
	<TestContext.Provider 
		value={{
			username: 'superawesome',
		}}
	>
		<div className="test">
			<Navbar />
			<Messages />
		</div>
	<TestContext.Provider/>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Copy the code

useImperativeHandle

UseImperativeHandle allows you to customize the instance value that is exposed to the parent component when using a ref. In simple terms, the child component can optionally expose methods to its subcomponent to hide private methods and attributes. UseImperativeHandle should be used with the forwardRef

const kun = useRef() const introduce = useCallback (() => { console.log('i can sing, jump, rap, play basketball') }, []) useImperativeHandle(ref, () => ({ introduce: () => { introduce() } })); return ( <div ref={kun}> { props.count }</div> ) } const KunKun = forwardRef(Kun) function App () { const [ count, setCount ] = useState(0) const kunRef = useRef(null) const onClick = useCallback (() => { setCount(count => count + 1) Kunref.current. Introduce ()}, []) return (<div> {count} <KunKun ref={count} count={count}></KunKun> <button onClick={onClick}>Copy the code

ref

There are three ways to create refs

The statement

reference

call

useRef

You can not only reference but also save data

The controlled components

High order component

Application scenarios

Strengthen the props

1, when each of the subcomponents needs to add a property, there is no need to modify the external component, only need to modify the internal component can be

Render judgment authentication

Life cycle hijacking

Reverse inheritance

class ComponentChild extends React.Component { constructor(props) { super(props) this.state = { num: 2019 } } componentDidMount() { console.log("child component Did Mount") } clickComponent() { // this.setState({num:2}) }  render() { return ( <div>{this.state.num}</div> ) } } let iihoc = WrapComponet => class extends WrapComponet { constructor(props) { super(props) this.state = { num: 2000 } } componentDidMount() { console.log('iihoc componentDidMount') console.log(this) this.clickComponent() // this.setState((pre) => ({ num: Pre.num + 1})} render() {return (<div> <div onClick={this.clickComponent}>'iiHoc click '</div> External components can call methods of inherited components. {/* <div><WrapComponet /></div> */}} {/* <div>< /div> */}} External components can also call methods of inherited components. <div>{super.render()}</div> </div> ) } } export default iihoc(ComponentChild)Copy the code

Commonly used higher-order components

Connect, withrouter, forwardRef

Adding ref directly to a function component raises an error and requires the forwardRef wrapper

portals

strictMode

Custom hooks

Very good article by custom hooks