主题提供者问题
Theme Provider issue
我正在尝试为一个小项目设置主题提供程序。每次用户单击按钮时,应用程序主题(颜色)都应该改变。假设我在一个单独的文件中有四个主题,如下所示:
const themesArray = [
{ primaryColor: '#483639', secondaryColor: '#F7F7F7' },
{ primaryColor: '#fb7051', secondaryColor: '#333' },
{ primaryColor: '#60b494', secondaryColor: '#F7F7F7' },
{ primaryColor: '#afb5c0', secondaryColor: '#333' }
];
export default themesArray;
每次用户单击按钮(嵌套在特定组件中)时,计数器都会递增到 3,如下所示:
import React, { useState, useContext } from 'react';
import themesArray from '../../styles/themesArray';
const ThemeContext = React.createContext();
const ThemeUpdateContext = React.createContext();
const useTheme = () => useContext(ThemeContext);
const useThemeUpdate = () => useContext(ThemeUpdateContext);
const ThemeProvider = ({ children }) => {
const [state, setState] = useState({
count: 0,
primaryColor: themesArray[0].primaryColor,
secondaryColor: themesArray[0].secondaryColor
});
const toggleTheme = () => {
setState(prevState => ({
count: prevState.count >= 3 ? 0 : ++prevState.count,
primaryColor: themesArray[prevState.count].primaryColor,
secondaryColor: themesArray[prevState.count].secondaryColor
}));
}
return (
<ThemeContext.Provider value={[state.primaryColor, state.secondaryColor]}>
<ThemeUpdateContext.Provider value={toggleTheme}>
{children}
</ThemeUpdateContext.Provider>
</ThemeContext.Provider>
);
}
export { ThemeProvider, useTheme, useThemeUpdate };
计数器似乎工作正常,但问题是我再也没有回到我的第一个对象值(我再也没有回到第一个主题颜色)。我的意思是当我 console.log(state.count, state.primaryColor, state.secondaryColor)
我得到这个:
0 #483639 #F7F7F7 ThemeContext.js:24
1 #fb7051 #333 ThemeContext.js:24
2 #60b494 #F7F7F7 ThemeContext.js:24
3 #afb5c0 #333 ThemeContext.js:24
0 #afb5c0 #333 ThemeContext.js:24
1 #fb7051 #333 ThemeContext.js:24
2 #60b494 #F7F7F7 ThemeContext.js:24
3 #afb5c0 #333 ThemeContext.js:24
0 #afb5c0 #333 ThemeContext.js:24
你知道为什么每次计数器值回到 0 时第一个对象的值都会被最后一个对象的值覆盖吗?
您正在改变状态 ++prevState.count
which is a problem。
Treat state as if it were immutable
此外,您可以改用模数:
const toggleTheme = () => {
setState(prevState => {
const nextCount = prevState.count + 1;
return {
count: nextCount % 3,
primaryColor: themesArray[nextCount].primaryColor,
secondaryColor: themesArray[nextCount].secondaryColor
};
});
};
完整示例:
const themesArray = [
{ primaryColor: "#483639", secondaryColor: "#F7F7F7" },
{ primaryColor: "#fb7051", secondaryColor: "#333" },
{ primaryColor: "#60b494", secondaryColor: "#F7F7F7" },
{ primaryColor: "#afb5c0", secondaryColor: "#333" }
];
const ThemeContext = React.createContext();
const ThemeUpdateContext = React.createContext();
const useTheme = () => useContext(ThemeContext);
const useThemeUpdate = () => useContext(ThemeUpdateContext);
const ThemeProvider = ({ children }) => {
const [state, setState] = useState({
count: 0,
primaryColor: themesArray[0].primaryColor,
secondaryColor: themesArray[0].secondaryColor
});
const toggleTheme = () => {
setState(prevState => {
const nextCount = prevState.count + 1;
return {
count: nextCount % 3,
primaryColor: themesArray[nextCount].primaryColor,
secondaryColor: themesArray[nextCount].secondaryColor
};
});
};
return (
<ThemeContext.Provider value={[state.primaryColor, state.secondaryColor]}>
<ThemeUpdateContext.Provider value={toggleTheme}>
{children}
</ThemeUpdateContext.Provider>
</ThemeContext.Provider>
);
};
const Button = () => {
const [primaryColor] = useTheme();
const toggle = useThemeUpdate();
return (
<button
onClick={toggle}
style={{ width: 500, height: 500, backgroundColor: primaryColor }}
>
Button
</button>
);
};
const App = () => {
return (
<ThemeProvider>
<Button />
</ThemeProvider>
);
};
我正在尝试为一个小项目设置主题提供程序。每次用户单击按钮时,应用程序主题(颜色)都应该改变。假设我在一个单独的文件中有四个主题,如下所示:
const themesArray = [
{ primaryColor: '#483639', secondaryColor: '#F7F7F7' },
{ primaryColor: '#fb7051', secondaryColor: '#333' },
{ primaryColor: '#60b494', secondaryColor: '#F7F7F7' },
{ primaryColor: '#afb5c0', secondaryColor: '#333' }
];
export default themesArray;
每次用户单击按钮(嵌套在特定组件中)时,计数器都会递增到 3,如下所示:
import React, { useState, useContext } from 'react';
import themesArray from '../../styles/themesArray';
const ThemeContext = React.createContext();
const ThemeUpdateContext = React.createContext();
const useTheme = () => useContext(ThemeContext);
const useThemeUpdate = () => useContext(ThemeUpdateContext);
const ThemeProvider = ({ children }) => {
const [state, setState] = useState({
count: 0,
primaryColor: themesArray[0].primaryColor,
secondaryColor: themesArray[0].secondaryColor
});
const toggleTheme = () => {
setState(prevState => ({
count: prevState.count >= 3 ? 0 : ++prevState.count,
primaryColor: themesArray[prevState.count].primaryColor,
secondaryColor: themesArray[prevState.count].secondaryColor
}));
}
return (
<ThemeContext.Provider value={[state.primaryColor, state.secondaryColor]}>
<ThemeUpdateContext.Provider value={toggleTheme}>
{children}
</ThemeUpdateContext.Provider>
</ThemeContext.Provider>
);
}
export { ThemeProvider, useTheme, useThemeUpdate };
计数器似乎工作正常,但问题是我再也没有回到我的第一个对象值(我再也没有回到第一个主题颜色)。我的意思是当我 console.log(state.count, state.primaryColor, state.secondaryColor)
我得到这个:
0 #483639 #F7F7F7 ThemeContext.js:24
1 #fb7051 #333 ThemeContext.js:24
2 #60b494 #F7F7F7 ThemeContext.js:24
3 #afb5c0 #333 ThemeContext.js:24
0 #afb5c0 #333 ThemeContext.js:24
1 #fb7051 #333 ThemeContext.js:24
2 #60b494 #F7F7F7 ThemeContext.js:24
3 #afb5c0 #333 ThemeContext.js:24
0 #afb5c0 #333 ThemeContext.js:24
你知道为什么每次计数器值回到 0 时第一个对象的值都会被最后一个对象的值覆盖吗?
您正在改变状态 ++prevState.count
which is a problem。
Treat state as if it were immutable
此外,您可以改用模数:
const toggleTheme = () => {
setState(prevState => {
const nextCount = prevState.count + 1;
return {
count: nextCount % 3,
primaryColor: themesArray[nextCount].primaryColor,
secondaryColor: themesArray[nextCount].secondaryColor
};
});
};
完整示例:
const themesArray = [
{ primaryColor: "#483639", secondaryColor: "#F7F7F7" },
{ primaryColor: "#fb7051", secondaryColor: "#333" },
{ primaryColor: "#60b494", secondaryColor: "#F7F7F7" },
{ primaryColor: "#afb5c0", secondaryColor: "#333" }
];
const ThemeContext = React.createContext();
const ThemeUpdateContext = React.createContext();
const useTheme = () => useContext(ThemeContext);
const useThemeUpdate = () => useContext(ThemeUpdateContext);
const ThemeProvider = ({ children }) => {
const [state, setState] = useState({
count: 0,
primaryColor: themesArray[0].primaryColor,
secondaryColor: themesArray[0].secondaryColor
});
const toggleTheme = () => {
setState(prevState => {
const nextCount = prevState.count + 1;
return {
count: nextCount % 3,
primaryColor: themesArray[nextCount].primaryColor,
secondaryColor: themesArray[nextCount].secondaryColor
};
});
};
return (
<ThemeContext.Provider value={[state.primaryColor, state.secondaryColor]}>
<ThemeUpdateContext.Provider value={toggleTheme}>
{children}
</ThemeUpdateContext.Provider>
</ThemeContext.Provider>
);
};
const Button = () => {
const [primaryColor] = useTheme();
const toggle = useThemeUpdate();
return (
<button
onClick={toggle}
style={{ width: 500, height: 500, backgroundColor: primaryColor }}
>
Button
</button>
);
};
const App = () => {
return (
<ThemeProvider>
<Button />
</ThemeProvider>
);
};