1. ホーム
  2. javascript

[解決済み] useContextでContextの値を変更するには?

2022-09-22 22:40:08

質問

を使用して useContext フックを使用すると、React 16.8+でうまく動作します。コンポーネントを作成し、フックを使用し、問題なくコンテキストの値を利用することができます。

確信が持てないのは、Context Providerの値に変更を加える方法です。

1) useContext フックは厳密にはコンテキスト値を消費する手段なのでしょうか。

2) React フックを使用して、子コンポーネントから値を更新するために推奨される方法はありますか。 useContext フックを使用しているすべてのコンポーネントのコンポーネントの再レンダリングをトリガーすることになりますか?

const ThemeContext = React.createContext({
  style: 'light',
  visible: true
});

function Content() {
  const { style, visible } = React.useContext(ThemeContext);

  const handleClick = () => {
    // change the context values to
    // style: 'dark'
    // visible: false
  }

  return (
    <div>
      <p>
        The theme is <em>{style}</em> and state of visibility is 
        <em> {visible.toString()}</em>
      </p>
      <button onClick={handleClick}>Change Theme</button>
    </div>
  )
};

function App() {
  return <Content />
};

const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.2/umd/react-dom.production.min.js"></script>

どのように解決するのですか?

フックを使ってコンテキストを更新する方法については コールバックを下に渡さないようにするには? の部分をご覧ください。

に渡される引数は createContext を使用するコンポーネントがある場合のみ、デフォルトの値になります。 useContext を使用するコンポーネントが Provider がありません。代わりに Provider を供給する stylevisibility という2つの文字列と、それらを切り替えるための関数があります。

const { createContext, useContext, useState } = React;

const ThemeContext = createContext(null);

function Content() {
  const { style, visible, toggleStyle, toggleVisible } = useContext(
    ThemeContext
  );

  return (
    <div>
      <p>
        The theme is <em>{style}</em> and state of visibility is
        <em> {visible.toString()}</em>
      </p>
      <button onClick={toggleStyle}>Change Theme</button>
      <button onClick={toggleVisible}>Change Visibility</button>
    </div>
  );
}

function App() {
  const [style, setStyle] = useState("light");
  const [visible, setVisible] = useState(true);

  function toggleStyle() {
    setStyle(style => (style === "light" ? "dark" : "light"));
  }
  function toggleVisible() {
    setVisible(visible => !visible);
  }

  return (
    <ThemeContext.Provider
      value={{ style, visible, toggleStyle, toggleVisible }}
    >
      <Content />
    </ThemeContext.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>