Вот CodeSandbox, в котором приведен пример кода, приведенный ниже, и подстилка подчеркивает некоторые из проблем: https://codesandbox.io/s/react-repl-bw2h1
Ниже приведена основа c пример того, что я пытаюсь сделать. В компоненте контейнера у меня есть контекст AppContext
, который предоставляет состояние дочерним компонентам, <ChildConsumer />
и <ChildDispatcher />
.
Компонент <ChildConsumer />
получает это состояние, используя useContext
, и это кажется, работает как ожидалось.
Внутри <ChildDispatcher />
, я пытаюсь отправить действие при нажатии кнопки. Для этого я создал редуктор reducer
, который обрабатывает действие. Я также настроил здесь useReducer, который принимает reducer
и начальное состояние store
.
Когда я нажимаю кнопку, ничего не происходит. То, что я ожидаю, это то, что dispatch
получает как state
оторванный от useReducer
, так и объект action
, и передает их редуктору. Редуктор должен видеть, что получено действие типа BUTTON_CLICKED
, и должен возвращать новое состояние, содержащее старое состояние, а также дополнительный элемент 'goodbye'
. Затем дочерний компонент <ChildConsumer />
должен выполнить повторное рендеринг с этим новым состоянием.
import React, { createContext, useContext, useReducer } from "react";
import ReactDOM from "react-dom";
const store = [""];
const AppContext = createContext(store);
const ChildDispatcher = () => {
const reducer = (state, action) => {
switch (action.type) {
case "BUTTON_CLICKED":
return [...state, "goodbye"];
default:
return state;
}
};
const [state, dispatch] = useReducer(reducer, store);
const handleClick = () =>
dispatch(state, {
type: "BUTTON_CLICKED"
});
return <button onClick={handleClick}>press me</button>;
};
const ChildConsumer = () => {
const [consumer] = useContext(AppContext);
return <div>{consumer}</div>;
};
const App = () => {
return (
<div>
<h1>Using Context and useReducer</h1>
<AppContext.Provider value={["hello"]}>
<ChildConsumer />
<ChildDispatcher />
</AppContext.Provider>
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);