es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

No se puede utilizar el Context de React en componentes descendientes profundos.

Estoy tratando de usar el estado global en mi aplicación React usando React Context y el hook useReducer. Cuando intento acceder al estado usando mi hook useStateContext en descendientes distantes, obtengo undefined. Para hablar de antemano, estoy usando react-three-fiber donde estoy obteniendo mi error de contexto.

App.js

const App = () => {
  return (
      <gameprovider>
        <appstate></appstate>
      </gameprovider>
  );
};

const AppState = () => {
  const state = useStateContext() // this works. Direct child of Provider
  return <game></game>
}

const Game = () => {
  const state = useStateContext(); // this works. 2nd descendant of Provider
  return <scene></scene>
};

const Scene = () => {
  const state = useStateContext(); // this works. 3rd descendant
  return (
    <div id="{styles.scene}">
      <canvas>
        <orbitcontrols mindistance="{9}" maxdistance="{9}"></orbitcontrols>
        <ambientlight intensity="{0.5}"></ambientlight>
        <spotlight position="{[10," 15,="" 10]}="" angle="{0.3}"></spotlight>
        <cube size="{5}" position="{[0," 0,="" 0]}=""></cube>
      </canvas>
    </div>
  );
};

const Cube = () => {
  const state = useStateContext(); // returns undefined. What gives?
  return <group></group>
}

StateContext.js

import React, { useContext, createContext, useReducer } from 'react'
import reducer from './reducer';

const StateContext = createContext();
const DispatchContext = createContext();

export const useDispatchContext = () => useContext(DispatchContext)
export const useStateContext = () => useContext(StateContext);

const initialState = {
     test: 1
}

export const GameProvider = ({ children }) => {
    const [state, dispatch] = useReducer(reducer, initialState)

    return (
        <dispatchcontext.provider value="{dispatch}">
            <statecontext.provider value="{state}">
                {children}
            </statecontext.provider>
        </dispatchcontext.provider>
    )
}

Quería usar Context ya que pensé que podría obtener el estado en cualquier descendiente de mi aplicación. He intentado revisar la documentación de React sobre este problema pero sin éxito.

EDIT:

También creo que podría ser importante mencionar que estoy usando react-three-fiber que está envolviendo mi componente de Cube en un Canvas .

Tags:  , ,

Answer

  1. Avatar for davy.ai

    El problema que está enfrentando parece estar relacionado con la jerarquía de sus componentes y cómo el useStateContext hook está consumiendo el contexto. Como el hook devuelve undefined en el componente Cube, esto significa que no puede encontrar el contexto.

    Una posible solución es crear un contexto nuevo específicamente para el componente Cube y envolverlo dentro del componente Scene. De esta manera, el componente Cube tendrá acceso a su propio contexto que es un hijo del contexto principal.

    Aquí hay un ejemplo de cómo se podría actualizar su código:

    const App = () => {
      return (
        <gameprovider>
          <appstate></appstate>
        </gameprovider>
      );
    };
    
    const AppState = () => {
      const state = useStateContext();
      return <game></game>;
    };
    
    const Game = () => {
      const state = useStateContext();
      return <scene></scene>;
    };
    
    const Scene = () => {
      const state = useStateContext();
      return (
        <statecontext.provider value="{state}">
          <div id="{styles.scene}">
            <canvas>
              <orbitcontrols mindistance="{9}" maxdistance="{9}"></orbitcontrols>
              <ambientlight intensity="{0.5}"></ambientlight>
              <spotlight position="{[10," 15,="" 10]}="" angle="{0.3}"></spotlight>
              <cube size="{5}" position="{[0," 0,="" 0]}=""></cube>
            </canvas>
          </div>
        </statecontext.provider>
      );
    };
    
    const CubeContext = createContext();
    
    const Cube = () => {
      const state = useContext(CubeContext);
      return <group></group>;
    };
    
    export const GameProvider = ({ children }) => {
      const [state, dispatch] = useReducer(reducer, initialState);
    
      return (
        <dispatchcontext.provider value="{dispatch}">
          <statecontext.provider value="{state}">
            <cubecontext.provider value="{state}">
              {children}
            </cubecontext.provider>
          </statecontext.provider>
        </dispatchcontext.provider>
      );
    };
    

    En este ejemplo, se crea un nuevo contexto llamado CubeContext específicamente para el componente Cube. A continuación, este contexto se envuelve dentro del componente Scene y se le proporciona el mismo valor de estado que el contexto principal.

    Finalmente, el componente Cube utiliza el hook useContext para consumir el CubeContext y recuperar el valor de estado.

    ¡Espero que esto ayude! No dude en ponerse en contacto conmigo si tiene más preguntas.

Comments are closed.