En la página de documentos de React 16 Context , tienen ejemplos que se parecen a este:
const defaultValue = 'light' const SomeContext = React.createContext(defaultValue) const startingValue = 'light' const App = () => ( <SomeContext.Provider theme={startingValue}> Content </SomeContext.Provider> ) Parece que el defaultValue es inútil porque si, en cambio, configura el valor startingValue en cualquier otra cosa o no lo configura (que no está undefined ), lo anula. Eso está bien, debería hacer eso.
Pero entonces, ¿cuál es el punto de defaultValue ?
Si quiero tener un contexto estático que no cambie, sería bueno poder hacer algo como a continuación, y simplemente pasar el proveedor a través del defaultValue
const App = () => ( <SomeContext.Provider> Content </SomeContext.Provider> )Cuando no hay un proveedor, el argumento defaultValue se usa para la función createContext . Esto es útil para probar componentes de forma aislada sin envolverlos o probarlos con diferentes valores del proveedor.
Ejemplo de código:
import { createContext, useContext } from "react"; const Context = createContext( "Default Value" ); function Child() { const context = useContext(Context); return <h2>Child1: {context}</h2>; } function Child2() { const context = useContext(Context); return <h2>Child2: {context}</h2>; } function App() { return ( <> <Context.Provider value={ "Initial Value" }> <Child /> {/* Child inside Provider will get "Initial Value" */} </Context.Provider> <Child2 /> {/* Child outside Provider will get "Default Value" */} </> ); }Solo comparto mi configuración típica cuando uso TypeScript, para completar la respuesta de @tiomno anterior, porque creo que muchos googlers que terminan aquí en realidad están buscando esto:
interface GridItemContextType { /** Unique id of the item */ i: string; } const GridItemContext = React.createContext<GridItemContextType | undefined>( undefined ); export const useGridItemContext = () => { const gridItemContext = useContext(GridItemContext); if (!gridItemContext) throw new Error( 'No GridItemContext.Provider found when calling useGridItemContext.' ); return gridItemContext; }; El gancho proporciona una escritura más segura en este escenario. El defaultValue undefined lo protege de olvidarse de configurar el proveedor.
Mis dos centavos:
Después de leer este instructivo artículo de Kent C. Dodds como de costumbre :), aprendí que el valor predeterminado es útil cuando desestructuras el valor devuelto por useContext:
Defina el contexto en una esquina del código base sin valor predeterminado:
const CountStateContext = React.createContext() // <-- define the context in one corner of the codebase without defaultValuey usarlo así en un componente:
const { count } = React.useContext(CountStateContext) JS obviamente dirá TypeError: Cannot read property 'count' of undefined
Pero simplemente no puede hacer eso y evitar el valor predeterminado por completo.
Acerca de las pruebas, mi maestro Kent tiene un buen punto cuando dice:
Los documentos de React sugieren que proporcionar un valor predeterminado "puede ser útil para probar componentes de forma aislada sin envolverlos". Si bien es cierto que le permite hacer esto, no estoy de acuerdo con que sea mejor que envolver sus componentes con el contexto necesario. Recuerde que cada vez que hace algo en su prueba que no hace en su aplicación, reduce la cantidad de confianza que la prueba puede brindarle.
Adicional para TypeScript ; si no desea utilizar un valor predeterminado, es fácil complacer a la pelusa haciendo lo siguiente:
const MyFancyContext = React.createContext<MyFancyType | undefined>(undefined)Solo necesita asegurarse de agregar las validaciones adicionales más adelante para asegurarse de haber cubierto los casos cuando MyFancyContext === indefinido
etc.