Изменить состояние реакции с помощью крючков

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

В примере у меня есть 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

Другие вопросы по тегам