首页 > 解决方案 > React-Redux:mapStateToProps 内部的逻辑不会导致重新渲染

问题描述

我想知道我在react-redux'smapStateToProps模式中看到的这种行为背后的“原因”。我没有把我所有的减速器、动作等都放在我的问题中,因为我认为这些不是问题所在。

video.component.tsx

const mapStateToProps = (state: RootState) => ({
  // valid activeVideoState are: 'prejoin' | 'active'
  prejoin: state.video.activeVideoState === 'prejoin', 
});

class _VideoComponent extends React.Component {

  componentDidMount () {
    this.checkJoinState();
  }

  componentWillUpdate () {
    this.checkJoinState();
  }

  async checkJoinState () {
    if (!this.props.prejoin) {
      // do stuff
    }
  }

  // rest of file class
}

// the `withRouter()` shouldn't affect anything
export const VideoComponent = withRouter(connect(
  mapStateToProps,
  null
)(_VideoComponent));

这是我的减速器的一个片段(只是为了确保我只使用副本而不是改变我的状态):

视频.reducer.ts


const initialState = {
  activeVideoState: 'prejoin',
};

export const videoReducer = (state = initialState, action) => {
  switch (action.type) {
    case VIDEO_STARTED: {
      return { ...state, activeVideoState: 'active' };
    }
    // other cases
  } 
  return state;
}

视频.actions.ts

export const sessionStarted = (sessionId: string) => ({
  type: VIDEO_STARTED,
  sessionId
});

服务.ts

import { store } from '@store/store';

// rxjs observable to listen to a WS for a video to start
this.onVideoStarted()
  .subscribe((session) => {
    // code 
    store.dispatch(sessionStarted(session.id));
  });

当组件最初呈现时state.video.activeVideoState === 'prejoin'总是. 但在组件的生命周期内,更改为. 这个组件的设置方式,即使我可以清楚地看到 redux 状态已经改变(使用 react-redux 浏览器扩展) ,也不会重新渲染。 truestate.video.activeVideoStateactiveVideoComponent

但是,如果我将函数更改为如下所示:

const mapStateToProps = (state: RootState) => ({
  // valid activeVideoState are: 'prejoin' | 'active'
  prejoin: state.video.activeVideoState === 'prejoin', 
  _iDontUseThis: state.video.activeVideoState
});

然后我的组件将更新并重新渲染。我只是好奇为什么会这样。我非常了解 redux 模式,但我不知道内部原理。我看到有一些选项可以传递给connect(). 也许该areStatesEqual()函数着眼于引用而不是值?

标签: javascriptreactjstypescriptreduxreact-redux

解决方案


这似乎根本不是问题redux。我只是碰巧注意到我使用了错误的组件挂钩。当我切换它们时,我的组件开始重新渲染。我无法让错误行为在回购中起作用:https ://codesandbox.io/s/basic-react-redux-example-en5cz

改变:

// deprecated
componentWillUpdate() { }
// to this
componentDidUpdate() { }

我不知道为什么这会有所不同,但确实如此。


推荐阅读