Как работает "ReactReduxContext.Consumer"? - PullRequest
0 голосов
/ 16 марта 2020

Я написал демо, чтобы попытаться понять, как работает "ReactReduxContext.Consumer", основной код такой:

Hello.tsx

export default function Hello() {
  return <ReactReduxContext.Consumer>
    {({store}) => {
      return <div>
        <ul>
          <input value={store.getState().name} onChange={(e) => store.dispatch(changeNameAction(e.target.value))}/>
          <div>{JSON.stringify(store.getState())}</div>
        </ul>
      </div>
    }}
  </ReactReduxContext.Consumer>
}

Entry.tsx

ReactDOM.render(
  <Provider store={store}>
    <Hello/>
  </Provider>,
  document.body
);

State.ts

export type State = {
  name: string
};

редуктор.ts

const initStore: State = {
  name: 'aaa'
}

export default function reducers(state = initStore, action: ChangeNameAction): State {
  switch (action.type) {
    case 'CHANGE_NAME':
      return {
        ...state,
        name: action.name
      };
    default:
      return state;
  }
}

action.ts

export type ChangeNameAction = {
  type: 'CHANGE_NAME',
  name: string,
}

export function changeNameAction(name: string): ChangeNameAction {
  return {
    type: 'CHANGE_NAME',
    name: name
  }
}

Отображается правильно:

enter image description here

Но если я наберу что-нибудь в текстовом поле, значение не меняется.

Я не уверен, почему это не работает.

Вот небольшая, но полная демонстрация этого вопроса: https://github.com/freewind-demos/typescript-react-redux-context-consumer-demo

1 Ответ

2 голосов
/ 16 марта 2020

ReactReduxContext - это контекст реагирования , содержащий текущее хранилище Redux.

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

Реагируют Redux connect() и useSelector и подписываются на хранилище и «уведомляют» Реакцию обновлений (обычно путем установки некоторого состояния, которое вызывает повторную визуализацию подписанного компонента).

Вы можете реализовать свою собственную примитивную версию useSelector, выполнив следующее:

function useSelector(f) {
  const store = React.useContext(ReactReduxContent);
  const [state, setNextState] = React.useState(() => {
    return f(store.getState());
  });

  React.useEffect(() => {
    return store.listen(state => {
      setNextState(f(store.getState()));
    });
  }, [f, store]);

  return state;
}

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

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