React-Redux: Logi c внутри mapStateToProps не вызывает повторного рендеринга - PullRequest
0 голосов
/ 10 января 2020

Мне интересно "почему", стоящее за этим поведением, которое я вижу в паттерне react-redux mapStateToProps. Я не включил все свои редукторы, действия и т. Д. c в мой вопрос, потому что я не думаю, что это проблемы.

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));

Вот фрагмент моего редуктора (только для того, чтобы я использовал только копии и не изменял свое состояние):

video.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;
}

video.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' всегда равен true. Но в течение срока службы компонента state.video.activeVideoState меняется на active. При настройке этого компонента VideoComponent никогда не рендерится повторно, даже несмотря на то, что я ясно вижу, что состояние редукса изменилось (с помощью расширения браузера response-redux).

Но , если я изменю свою функцию так, чтобы она выглядела следующим образом:

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

Тогда мой компонент будет обновляться и перерисовываться. Мне просто интересно, почему это происходит. Я довольно хорошо понимаю паттерн редукса, но не знаю, что такое внутреннее. Я видел, что есть вариантов , которые вы можете передать в connect(). Может быть, функция areStatesEqual() смотрит на ссылки, а не значения?

1 Ответ

0 голосов
/ 10 января 2020

Похоже, это не проблема с redux. Я просто случайно заметил, что использую неправильный компонентный хук. Когда я переключил их, мой компонент начал повторную визуализацию. Я не мог заставить ошибочное поведение работать в репо: https://codesandbox.io/s/basic-react-redux-example-en5cz

Изменено:

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

Я не знаю, почему это имело значение , но это сделал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...