'dispatch' 在 react 中使用 useReducer 和 useContext 时未定义
'dispatch' is not defined when using useReducer with useContext in react
我正在尝试找出如何使用 useContext
和 useReducer
调度方法从组件更改全局状态。
该组件只需单击即可更改页面的背景
这是我定义上下文的方式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
组件
const ThemeToggle = () => {
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>
);
}
您似乎无法访问 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 函数正在剥离集合 light/dark 案例中的状态。您需要保留现有状态。
const ThemeReducer = (state, action) => {
switch (action.type) {
case "SET_DARK":
return {
...state,
isLightTheme: false,
};
case "SET_LIGHT":
return {
...state,
isLightTheme: true,
};
default:
return state;
}
};
我正在尝试找出如何使用 useContext
和 useReducer
调度方法从组件更改全局状态。
该组件只需单击即可更改页面的背景
这是我定义上下文的方式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
组件
const ThemeToggle = () => {
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>
);
}
您似乎无法访问 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 函数正在剥离集合 light/dark 案例中的状态。您需要保留现有状态。
const ThemeReducer = (state, action) => {
switch (action.type) {
case "SET_DARK":
return {
...state,
isLightTheme: false,
};
case "SET_LIGHT":
return {
...state,
isLightTheme: true,
};
default:
return state;
}
};