REDUX: переменные хранилища, доступные через this.props, устарели, но store.getState () работает - PullRequest
0 голосов
/ 28 февраля 2020

Хорошо, привет!

У меня возникли некоторые проблемы, которых у меня никогда не было, - при доступе к переменным магазина через mapStateToProps. А именно, они никогда не меняются и всегда имеют свои значения по умолчанию, которые я установил в магазине ДО изменения их каким-либо образом. Если я звоню им по store.getState().reducer.x, мой код работает!

Вот мой магазин:

export const initialState = {
    isKeyManagementWindowOpen: false
};

const rootReducer = combineReducers({
    some: someReducer,
    settings: settingsComponentReducer
)};

const store = createStore(rootReducer, compose(applyMiddleware(thunk), window.__REDUX_DEVTOOLS_EXTENSION__ ? window.__REDUX_DEVTOOLS_EXTENSION__() : variable => variable));

export default store;

settingsComponentActions. js

export const TOGGLE_KEY_MANAGEMENT_WINDOW = 'TOGGLE_KEY_MANAGEMENT_WINDOW';

export const toggleKeyManagementWindow = isKeyManagementWindowOpen => {
  return { type: TOGGLE_KEY_MANAGEMENT_WINDOW, isKeyManagementWindowOpen};
}

settingsComponentReducer. js

export const settingsComponentReducer = (state = initialState, action) => {
  console.log(action);
  switch (action.type) {
    case Actions.TOGGLE_KEY_MANAGEMENT_WINDOW:
      return Object.assign({}, state, {
        isKeyManagementWindowOpen: action.isKeyManagementWindowOpen
      });
    default: return state;
  }
};

Единственное, что может вызывать проблемы, это то, что я звоню this.props в моем websocket's subscribe method.

Key. js

connectToWebsocket = ip => {
      const stompClient = Stomp.client(`url/receivekey`);
      stompClient.heartbeat.outgoing = 0;
      stompClient.heartbeat.incoming = 0;
      stompClient.debug = () => null;
      stompClient.connect({ name: ip }, frame => this.stompSuccessCallBack(frame, stompClient), err => this.stompFailureCallBack(err, ip));
  }

stompSuccessCallBack = (frame, stompClient) => {
    stompClient.subscribe(KEY_READER_NODE, keyData => {
      if (!this.props.isKeyManagementWindowOpen) {
        this.loginWithKey(keyData.body);
      } else {
        this.addToKeyList(keyData.body);
      }
    });
  }

Несмотря на то, что я предварительно установил isKeyManagementWindowOpen на true, он все равно разрешается на false. Если я поменяю !this.props.isKeyManagementWindowOpen на !store.getState().settings.isKeyManagementWindowOpen, код сработает, и он перейдет в this.addToKeyList(keyData.body).

Так что, если я поменяю местами, но оставлю каждый вызов магазина в this.addToKeyList как this.props., то это все значение по умолчанию тоже, что не имеет смысла. Это работает, только если я поменяю каждую this.props. строку на store.getState()....

const mapStateToProps = state => ({
    ...
    ...
    isKeyManagementWindowOpen: state.settings.isKeyManagementWindowOpen,
});

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Key));

. На данный момент мой код работает, но я бы хотел назвать props как this.props..., а не через store.getState().... Есть идеи, почему это могло произойти?

Спасибо!

Ответы [ 3 ]

0 голосов
/ 28 февраля 2020

Почему бы не использовать что-то подобное, так как вы не должны напрямую изменять общее состояние приложения, обновляйте его только в случае запуска действия, но распространяйте исходное состояние до обновления.

export const settingsComponentReducer = (state = initialState, action) => {
  console.log(action);
  switch (action.type) {
    case Actions.TOGGLE_KEY_MANAGEMENT_WINDOW:
      return {
        ...state,
        isKeyManagementWindowOpen: action.isKeyManagementWindowOpen
      });
    default: 
      return state;
  }
};
0 голосов
/ 28 февраля 2020

Проблема в том, что React не может обновить любое значение в this.props ко времени выполнения следующей строки кода.

На самом деле это не так проблема, связанная с Redux c. В любом компоненте React запуск изменения состояния в строке все равно приведет к тем же значениям props и state в следующей строке, поскольку текущая функция все еще выполняется, а React не сделано еще.

0 голосов
/ 28 февраля 2020

Похоже, вы используете глубокое состояние

При назначении объекта создаются только полные копии объектов. Итак, давайте попробуем устранить самую легкую причину.

export const settingsComponentReducer = (state = initialState, action) => {
  const newState = JSON.parse(JSON.stringify(state));

Затем используйте newState вместо состояния ниже. Это создаст глубокую копию вашего состояния и всегда будет новым объектом, заставляющим ваше приложение воспринимать его как новую опору и корректно перерисовывать.

...