Last active
September 16, 2020 14:03
-
-
Save thibaut-d/3c9e4869e8e959b5657db895011938b0 to your computer and use it in GitHub Desktop.
Shared state management with React Native and the Context API
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { FC } from "react"; | |
import MyComponent from "./MyComponent"; | |
import AnotherComponent from "./AnotherComponent"; | |
import { ContextProvider } from "./ContextProvider"; | |
const App: FC = () => { | |
return ( | |
<ContextProvider> | |
<MyComponent /> | |
<AnotherComponent /> | |
</ContextProvider> | |
); | |
} | |
export default App |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { createContext, FC } from 'react' | |
import useCustomHook, { UseCustomHookType, initialCustomHookContext } from './useCustomHook' | |
// Props type | |
interface Props { | |
/** Children components place, shall not be needed here with FC type, yet eslint requires it... */ | |
children: React.ReactNode | |
} | |
// Create the context objects | |
export const CustomHookContext = createContext<UseCustomHookType>(initialCustomHookContext) | |
/** | |
* Context provider for user data from firebase | |
* | |
* @param props - React | |
* @returns a context provider for user data | |
*/ | |
const ContextProvider: FC<Props> = ({ children }: Props) => { | |
// Get state from custom hook | |
const customHookReturns = useCustomHook() | |
// Allow this component to encapsulate a part of the app with the provider | |
// Such component could encapsulate several providers in a row | |
return ( | |
<CustomHookContext.Provider value={customHookReturns}> | |
{/* children transmit the providers to the rest of the app if the user is connected*/} | |
{children} | |
</CustomHookContext.Provider> | |
) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useContext, FC } from "react"; | |
import { StoreContext } from "./StoreProvider"; | |
const MyComponent: FC = () => { | |
const {input, setInput, output} = useContext(CustomHookContext); | |
// some awsome logic here | |
return <View>{output}</View>; | |
} | |
export default MyComponent |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Dispatch, SetStateAction, useEffect, useState } from 'react' | |
export interface UseCustomHookType { | |
/** documentation */ | |
input: string | null | |
/** documentation */ | |
setInput: Dispatch<SetStateAction<string | null>> | |
/** documentation */ | |
output: string | null | |
} | |
// This is used to initialize the context | |
export const initialCustomHookContext = { | |
input: null, | |
setInput: () => { | |
// eslint-disable-next-line @typescript-eslint/no-unused-vars | |
return (prevState: string | null): null => null | |
}, | |
output: null, | |
} as UseCustomHookType | |
/** | |
* Custom hook description | |
* | |
* @returns - {@link UseCustomHookType} | |
*/ | |
const useCustomHook = (): UseCustomHookType => { | |
const [input, setInput] = useState<string | null>(null) | |
const [output, setOutput] = useState<string | null>(null) | |
// calculate new output when input change | |
useEffect(() => { | |
let mounted = true | |
// Declaration | |
const inputToOutput = async (): Promise<void> => { | |
// incredible logic | |
const newOutput = await magicTrick(input) | |
// don't do that if the component un-mounted during the magic trick | |
if (mounted) setOutput(newOutput) | |
} | |
// launch | |
inputToOutput() | |
// Cleanup after un-mount | |
return (): void => { | |
mounted = false | |
} | |
}, [input]) | |
return { | |
input, | |
setInput, | |
output, | |
} | |
} | |
export default useCustomHook |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment