reactjs 在react中使用带useContext的useReducer时未定义“dispatch”

uubf1zoe  于 2023-02-12  发布在  React
关注(0)|答案(1)|浏览(193)

我试图弄清楚如何使用useContextuseReducer调度方法从组件网更改全局状态。
该组件只是应该改变一个点击页面的背景
下面是我如何定义上下文ThemeContext.js

import { createContext, useReducer } from "react";
import ThemeReducer from './ThemeReducer'

const INITIAL_STATE = {
    isLightTheme: true,
    light: {syntax: '#555', ui: '#ddd', bg: '#eee'},
    dark: {syntax: '#ddd', ui: '#333', bg: '#555'},
}

export const ThemeContext = createContext(INITIAL_STATE);

const ThemeContextProvider = ({ children }) => {
   const [state, dispatch] = useReducer(ThemeReducer, INITIAL_STATE);
    return ( 
        <ThemeContext.Provider value={{
            isLightTheme: state.isLightTheme,
            light: state.light,
            dark:  state.dark,
            dispatch,
        }}>
            {children}
        </ThemeContext.Provider>
     );
}     
export default ThemeContextProvider;

ThemeReducer.js为:

const ThemeReducer = (state, action) => {
    switch (action.type) {
      case "SET_DARK":
        return {
            isLightTheme: false,
        };    
      case "SET_LIGHT":
            return {
                isLightTheme: true,
            }; 
      default:
        return state;
    }
  };  
  export default ThemeReducer;

app.js:

function App() {
  return (
    <div className="App">
       <ThemeContextProvider>        
          <Navbar />
          <BookList />
          <ThemeToggle />
       </ThemeContextProvider>
    </div>
  );
}

export default App;

ThemeToggle.js组件
常量主题切换=()=〉{

return ( 
        <button onClick={()=>dispatch({type: "SET_DARK"})}>Change theme</button>
     );
}
 
export default ThemeToggle;

但是,我得到这个错误:

src/components/ThemeToggle.jsx
  Line 6:30:  'dispatch' is not defined

我不明白为什么。因为dispatch应该在上下文中。我想知道这里出了什么问题,我该如何修复它?
P.S BooKList组件

import  { useContext } from 'react'
import { ThemeContext } from '../context/ThemeContext';

const BookList = () => {
    const {isLightTheme, light, dark} = useContext(ThemeContext)
    const theme = isLightTheme ? light : dark;
    return ( 
        <div  style={{background : theme.ui , color: theme.syntax}}>
            <ul>
                <li stryle={{background: theme.ui}} >The way of kings</li>
                <li stryle={{background: theme.ui}} >The namoe fot the wind</li>
                <li stryle={{background: theme.ui}} >The Final empire</li>
            </ul>
        </div>
     );
}
watbbzwu

watbbzwu1#

您似乎无法访问ThemeToggle中的ThemeContext。请使用useContext挂接访问ThemeContext上下文值并解构dispatch函数。

const ThemeToggle = () => {
  const { dispatch } = useContext(ThemeContext);
  return ( 
    <button onClick={() => dispatch({type: "SET_DARK"})}>
      Change theme
    </button>
  );
}
 
export default ThemeToggle;

为了完整起见,将dispatch添加到默认上下文值中。

const INITIAL_STATE = {
  isLightTheme: true,
  light: {syntax: '#555', ui: '#ddd', bg: '#eee'},
  dark: {syntax: '#ddd', ui: '#333', bg: '#555'},
  dispatch: () => {},
}

export const ThemeContext = createContext(INITIAL_STATE);

ThemeReducer reducer函数在设置的明/暗情况下剥离状态,需要保留已有状态。

const ThemeReducer = (state, action) => {
  switch (action.type) {
    case "SET_DARK":
      return {
        ...state,
        isLightTheme: false,
      };
  
    case "SET_LIGHT":
      return {
        ...state,
        isLightTheme: true,
      };

    default:
      return state;
  }
};

相关问题