根据该链接:http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/
render()
可能由new props
触发。有人可以给我一个代码示例吗?我看不到道具如何更改调用渲染!请不要通过状态更改道具;然后是setState()
调用render()
...
答案 0 :(得分:0)
看看shouldComponentUpdate()-这是它的签名-它返回一个布尔值。道具在那里,因此您可以比较并手动说是否应更新组件。
shouldComponentUpdate(nextProps, nextState)
答案 1 :(得分:0)
对于功能组件React.memo
代替了shouldComponentUpdate
,它与类组件一起使用。
const myComponent = React.memo(props => {
...
code of React.FunctionComponent
...
},
(prevProps, nextProps) => prevProps.propA === nextProps.propA
);
React.memo
得到两个上面显示的参数:一个由memo
包装的React.FunctionComponent和一个返回布尔值的可选函数。
当函数返回true时,将不会重新渲染组件。如果省略该函数,则其React.memo
中的默认实现类似于React.PureComponent中shouldComponentUpdate
的实现。例如。它对props
进行了浅层比较,不同之处在于仅考虑了props
,因为功能组件不存在state
。
答案 2 :(得分:0)
使用挂钩显示更整洁。传递给ComponentB的新道具数据会导致ComponentB的重新渲染:
import React, { useState } from 'react'
import ComponentB from '...'
const ComponentA = props => {
const [data, setData] = useState(0) // data = 0
handleChangeProp = item => setData(item) // data = 1
return(
<div>
<button onClick{() => handleChangeProp(1)}
<ComponentB props={data} />
</div>
)
}
答案 3 :(得分:0)
是的,当您执行setState(newState)或传递更改的props时,组件将重新呈现,这就是为什么您无法进行突变的原因。以下无效,因为您将状态设置为突变状态。
export default function Parent() {
const [c, setC] = useState({ c: 0 });
console.log('in render:', c);
return (
<div>
<button
onClick={() =>
setC(state => {
state.c++;
console.log('state is:', state);
return state;
})
}
>
+
</button>
<Child c={c.c} />
</div>
);
}
该代码“不起作用”,因为按下+不会导致重新渲染,您先对状态进行了突变,然后使用相同的对象引用设置了状态,因此React不知道您进行了任何更改。
这是React检测更改的方式,您可能会认为将{c:0}
与{c:1}
进行比较是一种更改,但是由于您进行了突变,因此实际上没有任何更改:
const a = {c:1};
a.c++;//you "changed" a but a still is a
要指示React中的更改,您必须创建一个新引用:
const a = {c:1};
const b = {...a};//b is shallow copy of a
a===b;//this is false, even though both a and b have same internal values
这意味着您还可以具有意想不到的渲染,因为您创建的对象道具可能具有相同的值,但与上次创建时的引用仍然不同。
请注意,如果Child不是纯组件,则即使<Child prop={1}
也会导致Child呈现(请参阅最后的链接)。
您要避免做的是<Child prop={{c:value}}
,因为每次您传递prop时,即使value
没有变化,它都会强制Child进行渲染,React进行虚拟DOM比较。虚拟DOM比较可能仍会检测到子虚拟DOM与上次相同,并且不会进行实际的DOM更新。
您可以做的最昂贵的事情是<Child onEvent={()=>someAction(value)}
。这是因为现在虚拟DOM比较将失败,即使value和someAction不变。那是因为您每次都会创建一个新函数。
通常,您想记住在容器中创建道具的过程,here是使用react-redux钩子执行此操作的示例。 Here是一个有状态组件传递处理程序的示例。