Welcome to MLink Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
398 views
in Technique[技术] by (71.8m points)

javascript - ThemeProvider: "theme" prop is required. → React.js

?? Issue

I created a Custom Hook to switch themes, but I'm facing this problem and I don't exactly what could it be.

Basically, when I try to change the theme, it works perfectly. But, after refreshing the page, it doesn't stay with the correct one and gives me this error.

?? Reproduce the issue

You can reproduce this issue, cloning the Edite GitHub repository and follow the guide to set up the services.

?? Code

Note: see that src is the root

hooks/useThemeSwitcher.js

import { useState, useEffect } from 'react';

function useThemeSwitcher(key, initialTheme) {
  const [theme, setTheme] = useState(
    () => {
      let storagedTheme = localStorage.getItem(key);
      storagedTheme = JSON.parse(storagedTheme) || initialTheme;
    }
  );

  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(theme));
  }, [key, theme]);

  return [theme, setTheme];
}

export default useThemeSwitcher;

App.js

function App() {
  // Current theme state (light/dark);
  const [theme, setTheme] = useThemeSwitcher('theme', dark);

  const toggleTheme = () => {
    setTheme(theme.title === 'dark' ? light : dark)
  }

  return (
    <ThemeProvider theme={theme}>
      <Global />
      {/* ...components */}
      <ToolbarLeft toggleTheme={toggleTheme} />
    </ThemeProvider>
  );
}

components/Switch/index.js

// Components (styles)
import { CustomSwitch } from './switch.styles';

function Switch({ isToggled, onSwitch }) {
  return (
    <CustomSwitch>
      <input
        type="checkbox"
        checked={isToggled}
        onChange={onSwitch}
      />
      <span />
    </CustomSwitch>
  )
}

export default Switch;

components/Toolbar/Left/index.js

// Components (styles)
import { LeftContainer } from '../toolbar.styles';
// Components (children)
import ToolsList from './tools';

function ToolbarLeft({ toggleTheme }) {
  return (
    <LeftContainer>
      <ul>
        <ToolsList toggleTheme={toggleTheme} />
      </ul>
    </LeftContainer>
  )
}

export default ToolbarLeft;

components/Toolbar/Left/tools.js

function ToolsList({ toggleTheme }) {
  // Access and set the theme colors
  const { title } = useContext(ThemeContext);

  return (
    <>
      {/* ...components */}
      {/* Theme switcher */}
      <Switch
        isToggled={title === 'dark'}
        onSwitch={toggleTheme}
      </Switch>
    </>
  )
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The problem is that you are not returning storagedTheme inside your useThemeSwitcher hook.


So you could change your useThemeSwitcher.js to something like this:

import { useState, useEffect } from "react";

function useThemeSwitcher(key, initialTheme) {
  const [theme, setTheme] = useState(() => {
    let storagedTheme = localStorage.getItem(key);
    return JSON.parse(storagedTheme) || initialTheme;
  });

  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(theme));
  }, [key, theme]);

  return [theme, setTheme];
}

export default useThemeSwitcher;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to MLink Developer Q&A Community for programmer and developer-Open, Learning and Share
...