It may be a beginner question but any help would be much appriciated. I have an app that I created using React Native Expo. I have a file to store my Colors constant but I decided to add options to choose colors for the users. It should be condition based so I thought about using context API to pass the value to the file(it is a seperate file) and use it to state which color palette the user can choose. But since the Colors constant is not a component, I couldn't find a way to use the value of context. Is there a way to make the following constant "Colors" the way I tried? I used it in many screen components so far so it would be too much work to write it from scratch.
> import { AuthContext } from "../store/auth-context";
> import { useContext, useEffect} from "react";
>
> const purplePalette = {
> primary50: "#e4d9fd",
> primary100: "#c6affc",
> primary200: "#a281f0",
> primary400: "#5721d4",
> primary500: "#3e04c3",
> primary700: "#2d0689",
> primary800: "#200364",
> accent500: "#f7bc0c",
> error50: "#fcc4e4",
> error500: "#9b095c",
>
> gray300: "#dadae3",
> gray400: "#5d5b62",
> gray500: "#39324a",
> gray700: "#221c30",
> green400: "#2d9710",
> red400: "#683333",
> red300: "#a10707",
> yellow400: "#7f6e01",
> yellow300: "#bbcd1c",
>
> cyan400: "#47a6a7d6",
> orange100: "#f3ded4",
> orange200: "#e1af94",
> orange300: "#fc9c73",
> orange400: "#c06c14d6",
> orange500: "#9a5710d6",
> orange800: "#432302d6",
> };
>
> const orangePalette = {
> primary50: "#f2ece9",
> primary100: "#f3ded4",
> primary200: "#fc9c73",
> primary400: "#c06c14d6",
> primary500: "#9a5710d6",
> primary700: "#76430cd6",
> primary800: "#432302d6",
> accent500: "#f7bc0c",
> error50: "#fcc4e4",
> error500: "#9b095c",
>
> gray300: "#dadae3",
> gray400: "#5d5b62",
> gray500: "#39324a",
> gray700: "#221c30",
> green400: "#2d9710",
> red400: "#683333",
> red300: "#a10707",
> yellow400: "#7f6e01",
> yellow300: "#bbcd1c",
>
> cyan400: "#47a6a7d6",
> orange100: "#f3ded4",
> orange200: "#e1af94",
> orange300: "#fc9c73",
> orange400: "#c06c14d6",
> orange500: "#9a5710d6",
> orange800: "#432302d6",
> };
>
> let Colors;
>
> function getColors() {
> const authCtx = useContext(AuthContext);
> useEffect(() => {
> function dummy() {
> switch (authCtx.colorPalette) {
> case "default":
> return Colors = orangePalette;
> case "orange":
> return Colors = orangePalette;
> case "purple":
> return Colors = purplePalette;
> }
> }
> dummy();
> []);
> }
>
> getColors();
>
> export default Colors;`
I tried using SecureStore, AsyncStore to pass the condition value, made lots of research but none of them worked so far.
CodePudding user response:
You could create a custom hook that handles what you want. All components that want to access the context must be wrapped inside the provider, obviously.
Here is a minimal example on how this could be implemented.
import React, { useContext } from 'react'
const ColorPaletteContext = React.createContext()
export const ColorPaletteProvider ({ children }) => {
const [colorPaletteMode, setColorPaletteMode] = useState('orange')
return (
<ColorPaletteContext.Provider value={{ colorPaletteMode, setColorPaletteMode }}>
{children}
</ColorPaletteContext.Provider>
)
}
export const useColors = () => {
const { colorPaletteMode, setColorPaletteMode } = useContext(ColorPaletteContext)
const colorPalette = React.useMemo(() => {
let palette
if (colorPaletteMode === "purple") {
palette = purplePalette
} else {
palette = orangePalette
}
}, [colorPaletteMode])
return { colorPaletteMode, setColorPaletteMode, colorPalette }
}
Then, wrap your application in ColorPaletteProvider
.
default export function App() {
return <ColorPaletteProvider>
...
</ColorPaletteProvider>
}
Then, you can access the colorPalette
or the setColorPaletteMode
function inside any
CodePudding user response:
Your custom hook was really helpful and I was able to solve my question at last so thanks a lot. But the second part of the problem was how to use the colorPalette object in StyleSheet. So I changed the styles object to getStyles function and passed the palette as an argument. I am writing this in case someone else may have a similar problem.
function MyComponent(){
const Colors = useColors().colorPalette;
const styles = getStyles(Colors);
...
return(...)
}
const getStyles = (Colors) =>
StyleSheet.create({...})