Algunos experimentos que estoy haciendo con React me han dado el siguiente código:

const BreadNav = props => {
  const initial={
    stack:[
      {
        name:"Home",
        render:React.cloneElement(
          props.children,
          {pushElement:pushElement}
        ),
        state:{}
      }
    ],
  };

  const [state, setState] = React.useState(initial);

  const pushElement = (oldState,elem) => {
    let newStack = JSON.parse(JSON.stringify(state.stack));
    newStack[newStack.length-1].state = oldState;
    newStack.push(elem);
    setState({
      ...state,
      stack:newStack
    });
  }
  
  return(
    state.stack[state.stack.length-1].render
  );
}

React me da ReferenceError: can't access lexical declaration 'pushElement' before initialization que tiene sentido para el orden en que están las líneas. Si esto fuera C, simplemente lanzaría un prototipo de función para declarar pushElement y definirlo más tarde, pero no he visto una respuesta de javascript para esto. ¿Cómo evito este problema?

1
Bo Thompson 23 ene. 2021 a las 05:27

1 respuesta

La mejor respuesta

Puede utilizar una declaración de función, que es "izada", en lugar de asignar un valor de función a una variable const:

function BreadNav(props) {
  const initial = {
    stack: [
      {
        name: "Home",
        render: React.cloneElement(props.children, {pushElement}),
        state: {}
      }
    ],
  };

  const [state, setState] = React.useState(initial);

  function pushElement(oldState,elem) {
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    let newStack = JSON.parse(JSON.stringify(state.stack));
    newStack[newStack.length-1].state = oldState;
    newStack.push(elem);
    setState({
      ...state,
      stack: newStack
    });
  }
  
  return state.stack[state.stack.length-1].render;
}

Pero en este caso sería mucho más apropiado definir la función antes de usarla en el objeto initial literal:

const BreadNav = props => {
  const pushElement = (oldState, elem) => {
    let newStack = JSON.parse(JSON.stringify(state.stack));
    newStack[newStack.length-1].state = oldState;
    newStack.push(elem);
    setState({
      ...state,
      stack: newStack
    });
  };
  const initial = {
    stack: [
      {
        name: "Home",
        render: React.cloneElement(props.children, {pushElement}),
        state: {}
      }
    ],
  };

  const [state, setState] = React.useState(initial);
  
  return state.stack[state.stack.length-1].render;
}

Aún puede consultar las variables state y setState declaradas a continuación, están dentro del alcance, solo debe asegurarse de no llamar a la función antes de que se inicialicen.

3
Bergi 23 ene. 2021 a las 03:15