函数组件赋值相同的值视图不会渲染,类组件会,因为函数组件默认就阻止了
javascript
import {useState} from 'react'
export default function App() {
const [counter, setCounter] = useState(1)
console.log('App组件渲染了');
return(
<div>
<h1>{counter}</h1>
<button onClick={() => setCounter(1)}>+1</button>
</div>
)
}
使用memo:memo避免父组件更新时,子组件跟着更新
示例:在 App 组件内部修改 counter ,然后 counter2 作为 porps 传递给子组件,此时我们修改 counter 的状态时,子组件也会跟着更新,原因很简单,因为父组件更新了,那你子组件当然要重新更新。
App.jsx
javascript
import ChildCom from './components/ChildCom'
import {uesState} from 'react'
export default function App() {
const [counter, setCounter] = useState(1)
const [counter2, setCounter2] = useState(1)
console.log("App 渲染了")
return (
<div>
<div>{counter}</div>
<button onClick={() => setCounter1(counter + 1)}>+1</button>
<ChildCom1 counter={counter2} setCounter={setCounter2} />
</div>
);
}
ChildCom.jsx
javascript
import React from "react"
function ChildCom(props) {
console.log("ChildCom渲染了")
return (
<div>
<div>ChildCom1</div>
<div>{props.counter}</div>
</div>
);
}
export default ChildCom;
++子组件的更新是没有必要的,因为传递给子组件的 props 并没有发生变化++ ,我们就可以使用 React.memo ,之后我们再更新 counter 时,由于传递给子组件的 counter2 这个 props 属性并没有变化,因此子组件不会更新。
javascript
import React from "react"
function ChildCom(props) {
console.log("ChildCom渲染了")
return (
<div>
<div>ChildCom</div>
<div>{props.counter}</div>
</div>
);
}
export default React.memo(ChildCom);
React.memo只做浅比较,比如修改数组的话,子组件不会更新
javascript
import React, { useState } from 'react';
import ChildCom1 from "./components/ChildCom1"
function App() {
const [counter1, setCounter1] = useState(2);
const [stu, setStu] = useState(["张三","李四"]);
console.log("App 渲染了");
function clickHandle(){
setCounter1(counter1 + 1);
stu.push("王武");
setStu(stu)
}
return (
<div>
<div>{counter1}</div>
<button onClick={clickHandle}>+1</button>
<ChildCom1 stu={stu} setStu={setStu} />
</div>
);
}
export default App;
javascript
import React, {memo} from "react"
function ChildCom1(props) {
console.log("ChildCom1 渲染了")
const lis = props.stu.map((it,index)=>(<li key={index}>{it}</li>))
return (
<div>
<div>ChildCom1</div>
<ul>{lis}</ul>
</div>
);
}
export default memo(ChildCom1);
你需要对原数组进行深拷贝,然后再赋值给原数组
javascript
function clickHandle(){
setCounter1(counter1 + 1);
const arr = [...stu];
arr.push("王五");
setStu(arr)
}
默认情况下React.memo只会对对象做浅比较,如果你想要控制这个过程,请在第二个参数里面写上你自己的控制流程
javascript
function MyComponent(props) {
/* 使用 props 渲染 */
}
function areEqual(prevProps, nextProps) {
/*
如果把 nextProps 传入 render 方法的返回结果与
将 prevProps 传入 render 方法的返回结果一致则返回 true,
否则返回 false
*/
}
export default React.memo(MyComponent, areEqual);