不应该触发我们的效果触发

问题描述 投票:0回答:1

我有一个带有prop的react组件,该组件通过redux connect方法传递。有一个useEffect专门链接到该道具,该道具应该在更改时执行异步调用。问题是,无论我在道具上附加了useEffect而不更改,只要我在该应用中的其他任何地方更改redux状态,都会触发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 connect设置的兄弟组件,而prop映射的状态不同。

reactjs redux react-redux use-effect
1个回答
0
投票

当reducer运行时,您将拥有一个全新的状态对象,因此有了一个新的userPhoneNumber prop参考。您应该记住userPhoneNumber值。我使用reselect创建记忆状态选择器,但您可能可以使用useMemo钩子,并在效果的依赖项中使用that记忆值。

const memoizedUserPhoneNumber = useMemo(() => userPhoneNumber, [userPhoneNumber]);

useEffect(() => {
  if (memoizedUserPhoneNumber) {
    myAsyncFunction()
      .then(() => {
        showData()
      })
  }
}, [memoizedUserPhoneNumber]);

使用重新选择

import { createSelector } from 'reselect';

const appState = state => state.appState || {};

const userPhoneNumber = createSelector(
  appState,
  appState => appState.userPhoneNumber;
);

...

const mapStateToProps = state => {
  return {
    userPhoneNumber: userPhoneNumber(state),
  }
}

尽管这些都没有阻止父母重新渲染整个功能组件,所以要解决此问题,您需要使用memo HOC帮助“记忆”馈入组件的道具。

memo
© www.soinside.com 2019 - 2024. All rights reserved.