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