Home > Net >  creating a conditional constant to be used in other screens in React Native
creating a conditional constant to be used in other screens in React Native

Time:12-15

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