skip to Main Content

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.

2

Answers


  1. Chosen as BEST ANSWER

    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({...})
    

  2. 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

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search