In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-29 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly introduces "how to understand the rendering logic of React hooks". In daily operation, I believe many people have doubts about how to understand the rendering logic of React hooks. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful for you to answer the questions of "how to understand the rendering logic of React hooks"! Next, please follow the editor to study!
Due to the complexity of the project environment, if it is a pure class component, then it is component, pureComponent, shouldComponentUpdate and so on to control whether to re-render, but hooks seems to be more scenarios, and then break one by one.
In scenario 1, the parent component uses hooks and the child component uses class Component
Parent component
Export default function Test () {const [state, setState] = useState ({a: 1, b: 1, c: 1}); const [value, setValue] = useState (11) Return (state {state.a}, {state.b} {/ / @ ts-ignore setState ({a: 2, b: 1}) / / @ ts-ignore setState ({a: 2, b: 2}); console.log (state, 'state') }} > Test value {value} {setValue (value + 1) } > Test);}
Sub-component
Export default class App extends React.Component {render () {const {props} = this; console.log ('demo render'); return ({props.value.a}, {props.value.b});}}
As a result, each time you click the test button in the figure, the subcomponent Demo re-render:
Summary: every time the parent component (hook) is updated, a new state and value object will be exported, and the child component will definitely be updated (if no special treatment is done)
Scenario 2, the parent component uses hooks and the child component uses class PureComponent
The parent component code is the same as above, and the child components use PureComponent:
Export default function Test () {const [state, setState] = useState ({a: 1, b: 1, c: 1}); const [value, setValue] = useState (11) Return (state {state.a}, {state.b} {/ / @ ts-ignore setState ({a: 2, b: 1}) / / @ ts-ignore setState ({a: 2, b: 2}); console.log (state, 'state') }} > Test value {value} {setValue (value + 1) } > Test);}
Subcomponents use PureComponent:
Export default class App extends React.PureComponent {render () {const {props} = this; console.log ('demo render'); return ({props.value.a}, {props.value.b});}}
The resulting subassembly will still render every time:
Conclusion: the conclusion is the same as above, it is true that the dependent props has changed, because the parent component is hook mode, and the new value and state are directly exported for each update.
Scenario 3, figure out the difference between hook's setState and class component setState
Theory: the setState of class, if you pass in an object, it will be merged asynchronously, if you pass in a function, then the replacement will be performed immediately, and the setState of hook will be replaced directly, so is setState asynchronous or synchronous in hook?
Practice:
Component A:
Export default function Test () {const [state, setState] = useState ({a: 1, b: 1, c: 1}); const [value, setValue] = useState (11) Return (state {state.a}, {state.b}, {state.c} {/ / @ ts-ignore setState ({a: 2}); / / @ ts-ignore setState ({b: 2}) Console.log (state, 'state');}} > Test value {value} {setValue (value + 1) } > Test);}
I set the value of state in setState twice as {astate 2} and {bRV 2} respectively, so it is a merge, so I finally get that the state should be {aVaR2 Magnum BRV 2 and cRV 1}. If it is a replacement, then the final state is {BRV 2}.
Results:
When the test button is clicked, the state becomes {b 2}, and the whole value is replaced with {bju 2}.
Conclusion: the setState of hook is a direct replacement, not a merger.
Scenario 4, the parent component uses class and the child component uses hook
Parent component:
Export default class App extends React.PureComponent {state = {count: 1,}; onClick = () = > {const {count} = this.state; this.setState ({count: count + 1,});}; render () {const {count} = this.state; console.log ('father render') Return;}}
Subcomponents:
Interface Props {count: number;} export default function App (props: Props) {console.log (props, 'props'); return {props.count};}
Logic: the parent component (class component) calls setState, refreshes itself, then passes it to the hooks child component, and then re-invokes from the component to update
Scene 5
But at this point, I need to achieve the same effect as the PureComponent of a class component, and I need to use React.memo
Modify the parent component code to:
Export default class App extends React.PureComponent {state = {count: 1, value: 1,}; onClick = () = > {const {value} = this.state; this.setState ({count: value + 1,});}; render () {const {count, value} = this.state Console.log ('father render'); return ({value} Test);}}
The child component is added to memo, and the code is modified as follows:
Import React, {useState, memo} from 'react'; interface Props {count: number;} function App (props: Props) {console.log (props,' props'); return {props.count};} export default memo (App)
Logic at this point: the class component changes its own state, refreshes itself, from top to bottom, passes a unchanged props to the hooks component, and the hooks component wraps itself with memo.
Results:
We used memo to achieve the effect of PureComponent, and compared it once.
Scenario 6, hook,setState is the same value every time
Export default class App extends React.PureComponent {state = {count: 1, value: 1,}; onClick = () = > {const {value} = this.state; this.setState ({value: 1,}); render () {const {count, value} = this.state Console.log ('father render'); return ({value} Test);}}
Result: because the value set each time is the same (all 1), hooks will not be updated, just like class
Scenario 7, both parent and child components use hook
The parent component passes count to the child component
Export default function Father () {const [count, setCount] = useState (1); const [value, setValue] = useState (1); console.log ('father render') return (value {value} {setValue (value + 1)) } > Test);}
Subcomponents use count
Export default function App (props: Props) {console.log (props, 'props'); return {props.count};}
Result: each click on the test will cause the subcomponent to re-render
Sub-components join memo
Function App (props: Props) {console.log (props, 'props'); return {props.count};} export default memo (App)
Results:
The subcomponent does not trigger an update
Here, unlike the PureComponent of the first case class, the render child of the first case class is re-render at this time, because the parent component hooks does export new PureComponent and state with each update. This is called once, and the same state is set. So do not update at this time
Scenario 8, parent component hook, child component hook, using useCallback cache function
Parent component:
Export default function App () {const [count1, setCount1] = useState (0); const [count2, setCount2] = useState (0); const handleClickButton1 = () = > {setCount1 (count1 + 1);}; const handleClickButton2 = useCallback (() = > {setCount2 (count2 + 1);}, [count2]); return (Button1 Button2);}
Subcomponents:
Import React from 'react'; const Button = (props: any) = > {const {onClickButton, children} = props; return ({children} {Math.random ()});}; export default React.memo (Button)
Results: although we used memo. But click demo1, only the number after demo1 has changed, demo2 has not changed, click demo2, both numbers have changed.
So let's take a look without using useCallback.
The parent component modifies the code to remove the useCallback
Export default function App () {const [count1, setCount1] = useState (0); const [count2, setCount2] = useState (0); const handleClickButton1 = () = > {setCount1 (count1 + 1);}; const handleClickButton2 = () = > {setCount2 (count2+ 1);} Return (Demo1 Demo);}
The subcomponent code remains the same, and as a result, two numbers change each time.
The official interpretation of useCallback:
Is to return a function that is updated only when the dependency changes (returns a new function)
Conclusion:
The handleClickButton1 we declared defines a method directly, which causes a new method to be declared here whenever the parent component is re-rendered (state or props update). Although the new method is the same as the old method, it is still two different objects. After React.memo comparison, it finds that the object props changes and renders it again.
Const a = () = > {} const b = () = > {} astatum / / false
We all understand this truth, so we won't explain it.
Scenario 9, remove the count2 field from the dependent array
Import React, {useState, useCallback} from 'react'; import Demo from'. / Demo'; export default function App () {const [count2, setCount2] = useState (0); const handleClickButton2 = useCallback (() = > {setCount2 (count2 + 1);}, []); return (Test);}
In this way, the value of count2 is always 0, then the component will not reexport the setCount2 method, the handleClickButton2 function will never change, and the Button will only be updated once, that is, when the props received by the Demo component arrives from 0 to 1. Continue to click, count2 is also 0, but props once caused the Demo subcomponent to be updated from 0-1, but count2 is always 0, which is critical
Scenario 10, use useMemo to cache objects to achieve the effect of useCallback
Before use
Export default function App () {const [count, setCount] = useState (0); const [value, setValue] = useState (0); const userInfo = {age: count, name: 'Jace',} Return ({value} {setValue (value + 1);}} >);}
The sub-component uses memo, which does not depend on value, but on count.
But as a result, every time the parent component modifies the value of value, although the child component does not depend on value and uses a memo package, it is re-rendered every time.
Import React from 'react'; const Button = (props: any) = > {const {userInfo} = props; console.log (' sub render'); return ({userInfo.count});}; export default React.memo (Button)
Post-use useMemo
Const [count, setCount] = useState (0); const obj = useMemo (() = > {return {name: "Peter", age: count};}, [count]); return
Obviously, in the first way, every time the hook component is updated, hook will export a new count,const and declare a new obj object, which will be considered a new object even if it is wrapped in memo.
Look at the result of the second:
The parent component is updated so that the child component is no longer affected.
At this point, the study of "how to understand the rendering logic of React hooks" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.