深色主题/带钩

时间:2020-02-15 19:37:51

标签: reactjs material-ui react-hooks

你好,我有一个自定义钩子来定义主题

代码:

export default function App() {
  const [theme, setTheme] = usePersistedState('light');
  const toggleTheme = () => {
    setTheme(theme.type === 'light' ? 'dark' : 'light');
  };
  return (
    <ThemeProvider theme={theme}>
      <GlobalStyle />
      <div className="App">
        <button onClick={toggleTheme}>a</button>
      </div>
    </ThemeProvider>
  );

这是我的钓钩:

import { darkTheme, lightTheme } from '../themes/index';

function usePersistedState(key) {
  const [state, setState] = useState(() => {
    switch (key) {
      case 'dark':
        return darkTheme;
      case 'light':
        return lightTheme;
      default:
        return lightTheme;
    }
  });
  console.log(state);
  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(state.type));
  }, [key, state]);

  return [state, setState];
}

export default usePersistedState;

基本上,每次状态更改时,我都会将其保存到本地存储中,但是由于某种原因,它只能在第一次使用时

当我第二次尝试更改主题时,我没有输入开关

编辑:

enter image description here

因为我第一次在gif中显示,是因为我输入了开关,所以我得到了一个对象,但是当我尝试更改主题时,我只得到一个文本提示,因为我没有输入开关

2 个答案:

答案 0 :(得分:0)

您提供给useState的参数将仅在第一个渲染器上应用
在下一个渲染中,将应用您提供给setState函数的内容(您提供'light''dark',因此状态值将为“浅” “暗”

对于您的用例,您希望切换用例在每次状态更改时都运行,useReducer比useState(我认为)更好。

import { useReducer } from 'react';
import { darkTheme, lightTheme } from '../themes/index';


function usePersistedState(key) {
  const [state, dispatch] = useReducer(reducer, null, getTheme(key)); // first argument is the reducer function. second argument is the initial state. third argument is an init function (for complex initialization)

  const reducer = (state, action) => { // this will run on every state change (on every dispatch call)
    return getTheme(action.type)();
  }

  const getTheme = (themeType) => () => {
    switch (themeType) {
      case 'dark':
        return darkTheme;
      case 'light':
        return lightTheme;
      default:
        return lightTheme;
    }
  }

  console.log(state);
  useEffect(() => {
    localStorage.setItem('themeType', JSON.stringify(state));
  }, [state]);

  return [state, dispatch];
}

export default usePersistedState;

然后从组件中调用调度,如下所示:

export default function App() {
  const [theme, setTheme] = usePersistedState('light');
  const toggleTheme = () => {
    setTheme(theme.type === 'light' ? {type: 'dark'} : {type: 'light'});
  };
  return (
    <ThemeProvider theme={theme}>
      <GlobalStyle />
      <div className="App">
        <button onClick={toggleTheme}>a</button>
      </div>
    </ThemeProvider>
  );

答案 1 :(得分:0)

我认为您忘了用{type:...}

在对象上添加对象包装
import { MyModuleRoutingModule } from './MyModule-routing.module';
@NgModule({
  declarations: [
    MyComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,      
    AppRoutingModule 
  ],
  providers: [],
  bootstrap: [AppComponent] 
})
export class MyModule { }