Изменить состояние реакции с помощью крючков - PullRequest
1 голос
/ 22 марта 2019

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

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

2 голосов
/ 22 марта 2019

Как вы заметили, пользовательские ловушки предназначены для совместного использования логики с отслеживанием состояния , а не state .

Если вы хотите поделиться частью состояния, вы можете использовать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>
1 голос
/ 22 марта 2019

Чтобы выполнить эту задачу, вы должны поделиться своим состоянием через контекстный 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

...