arctic
arctic

Reputation: 819

How do I avoid passing the same prop to every component?

I am working on a React project.

In the following code, you can see that I am passing the same prop (theme: boolean value representing whether the app is currently toggled to dark mode or light mode) to every component. The reason I am passing theme to every component is because I use it to determine which mode I should style each component (using styled-components) in. This action of passing the same prop to every component seems redundant. How do I avoid the redundancy?

const App = () => {
  const [theme, setTheme] = persist('theme', true);

  return (
    <React.StrictMode>
      <div className='app'>
        <Toggle theme={theme} setTheme={setTheme} />
        <About theme={theme} />
        <Links theme={theme} />
        <Footer theme={theme} />
        <Background theme={theme} />
      </div>
    </React.StrictMode>
  );
};

Here is the code for the persist hook if it useful:

import React from 'react';

const persist = (key, defaultValue) => {
  const [state, setState] = React.useState(() => {
    const persistentState = localStorage.getItem(key);

    return persistentState ? JSON.parse(persistentState) : defaultValue;
  });

  React.useEffect(() => {
    window.localStorage.setItem(key, JSON.stringify(state));
  }, [state, key]);
  return [state, setState];
};

export default persist;

Upvotes: 2

Views: 282

Answers (1)

Lakshya Thakur
Lakshya Thakur

Reputation: 8316

React Context will come handy in here. You can create a ThemeProvider like so :-

const ThemeContext = React.createContext({
  isDark: false,
  setIsDark:()=>void
});

const ThemeProvider = ({
  children,
}) => {
   const [isDark, setIsDark] = usePersistentState('theme', true); // default: dark mode

  return (
    <ThemeContext.Provider value={{
    isDark,
    setIsDark,
  }}>
      {children}
    </ThemeContext.Provider>
  );
};

export default ThemeProvider;

Then you can wrap your respectable root App component or whatever you have inside this ThemeProvider like so :-

<ThemeProvider>
<App/>
</ThemeProvider>

Now in say, Links you can use the context this way :-

const {isDark,setIsDark} = useContext(ThemeContext);

I implemented something similar some time back for one of my app. You can take a reference from here (Ignore the TypeScript bit) -

Upvotes: 4

Related Questions