【发布时间】:2020-09-25 01:52:55
【问题描述】:
我有一个带有 props 的 react 组件,它由 redux 连接方法传递。有一个 useEffect 专门链接到该道具,它应该在它更改时执行异步调用。问题是每当我在该应用程序中的任何其他位置更改 redux 状态时,useEffect 都会触发,尽管我将 useEffect 附加到不改变的道具。
useEffect 方法是这样的
useEffect(() => {
if (userPhoneNumber) {
myAsyncFunction()
.then(() => {
showData()
})
}
}, [userPhoneNumber])
userPhoneNumber 属性通过 react-redux connect 方法传递,如下所示:
const mapStateToProps = state => {
return {
userPhoneNumber: state.appState.userPhoneNumber
}
}
export default connect(mapStateToProps)(MyComponent)
据我了解,这可能会在两个潜在的地方发生故障。一方面,如果 userPhoneNumber 道具没有改变,则不应触发 useEffect 。此外,mapStateToProps 方法没有返回新值,因此它不应该触发任何类型的重新渲染。
导致意外 useEffect 调用的 redux 状态更改来自同级组件,这些组件具有与该组件类似的 react-redux 连接设置,具有不同的 state 到 prop 映射。
【问题讨论】:
-
userPhoneNumber 是字符串还是对象?
-
当 reducer 运行时,您将拥有一个全新的状态对象,因此是一个新的
userPhoneNumber属性引用。你应该记住userPhoneNumber的值。我使用reselect 来创建记忆状态选择器,但您可能可以使用useMemo钩子并在依赖项中使用 that 记忆值以获得效果。 -
@DrewReese 尽管 redux 为每个对象创建了一个新的 state 对象,但它只是一个浅拷贝,只有被 reducer 更改的节点是一个新对象。所有其他节点将是同一个对象。所以除非调度动作没有改变
userPhoneNumberoldState.userPhoneNumber === newState.userPhoneNumber -
@SubinSebastian
mapStateToProps正在返回一个新对象。 github.com/reduxjs/reselect#motivation-for-memoized-selectors -
Also, the mapStateToProps method is not returning a new value so it should not be triggering any sort of a rerender如果父组件重新渲染,每个 React 组件都会重新渲染,除非它是Pure Component。要制作一个纯函数组件,你必须用React.memo包装它
标签: reactjs redux react-redux use-effect