How to change Context value while using React Hook of useContext

前端 未结 2 552
情书的邮戳
情书的邮戳 2020-12-04 17:27

Using the useContext hook with React 16.8+ works well. You can create a component, use the hook, and utilize the context values without any issues.

What

相关标签:
2条回答
  • 2020-12-04 17:52

    How to update context with hooks is discussed in the How to avoid passing callbacks down? part of the Hooks FAQ.

    The argument passed to createContext will only be the default value if the component that uses useContext has no Provider above it further up the tree. You could instead create a Provider that supplies the style and visibility as well as functions to toggle them.

    Example

    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>

    0 讨论(0)
  • 2020-12-04 18:11

    You can use this approach, no matter how many nested components do you have it will work fine.

    // Settings Context - src/context/Settings
    import React, { useState } from "react";
    
    const SettingsContext = React.createContext();
    
    const defaultSettings = {
       theme: "light",
    };
    
    export const SettingsProvider = ({ children, settings }) => {
       const [currentSettings, setCurrentSettings] = useState(
          settings || defaultSettings
       );
    
       const saveSettings = (values) => {
         setCurrentSettings(values)
       };
    
       return (
          <SettingsContext.Provider
             value={{ settings: currentSettings, saveSettings }}
          >
             {children}
          </SettingsContext.Provider>
       );
    };
    
    export const SettingsConsumer = SettingsContext.Consumer;
    
    export default SettingsContext;
    
    // Settings Hook - src/hooks/useSettings
    import { useContext } from "react";
    import SettingsContext from "src/context/SettingsContext";
    
    export default () => {
       const context = useContext(SettingsContext);
    
       return context;
    };
    
    // src/index
    ReactDOM.render(
       <SettingsProvider settings={settings}>
             <App />
       </SettingsProvider>,
       document.getElementById("root")
    
    // Any component do you want to toggle the theme from
    // Example: src/components/Navbar
    const { settings, saveSettings } = useSettings();
    
    const handleToggleTheme = () => {
      saveSettings({theme: "light"});
    };
    
    0 讨论(0)
提交回复
热议问题