Изменить состояние реакции с помощью крючков
Я хотел бы иметь глобальную переменную, которую я могу редактировать в любом месте, используя хуки.
В примере у меня есть 2 компонента, которые используют один и тот же хук. Мне кажется, что External toggle
редактирует свою собственную область count
а также Internal Toggle
также меняет свою сферу.
Возможно ли, чтобы оба переключателя редактировали одни и те же данные?
Пример кода: https://codesandbox.io/s/520zvyjwlp
index.js
function ChangeCount() {
const { count, increment } = useCounter();
return <button onClick={() => increment(!count)}>External Toggle</button>;
}
function App() {
const { count, increment } = useCounter();
return (
<div>
{`${count}`}
<br />
<ChangeCount />
<br />
<button onClick={() => increment(!count)}>Internal Toggle</button>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
useCount.js
import { useState } from "react";
export default function useCounter() {
const [count, setCount] = useState(false);
const increment = (changeCount) => setCount(changeCount);
return { count, increment };
}
2 ответа
Как вы заметили, пользовательские хуки предназначены для обмена логикой с учетом состояния, а не с фактическим состоянием
Если вы хотите поделиться частью государства, вы можете использовать context
особенность и передатьcount
переменная иincrement
функция в объекте к value
опора Provider
и потреблять его дальше вниз по дереву с useContext
,
пример
const { createContext, useContext, useState } = React;
const CounterContext = createContext();
function ChangeCount() {
const { increment } = useContext(CounterContext);
return <button onClick={increment}>External increment</button>;
}
function App() {
const [count, setCount] = useState(0);
function increment() {
setCount(count + 1);
}
return (
<CounterContext.Provider value={{ count, increment }}>
<div>{count}</div>
<ChangeCount />
<button onClick={increment}>Internal increment</button>
</CounterContext.Provider>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
Чтобы выполнить эту задачу, вы должны поделиться своим состоянием через контекстный API,
рассмотреть следующее:
const CounterContext = React.createContext({
count: 0,
increment: () => null,
});
const changeCount = () => {
const counter = useContext(CounterContext);
return <button onClick={() => counter.increment(!counter.count)}>External Toggle</button>;
}
const App = () => {
const { count, increment } = useCounter();
return (
<CounterContext.Provider value={{ count, increment }}>
{`${count}`}
<br />
<ChangeCount />
<br />
<button onClick={() => increment(!count)}>Internal Toggle</button>
</CounterContext.Provider>
);
}
Для получения дополнительной информации, пожалуйста, посетите: https://reactjs.org/docs/context.html