Dentro de un componente de la aplicación React, estoy llamando a una API y almacenando la respuesta dentro de un estado local. Luego quiero desestructurar el objeto que está almacenado en ese estado, pero no puedo simplemente desestructurar justo debajo de useEffect porque arrojará un error antes de que se complete la llamada.

Además, no quiero dividir el objeto dentro del useEffect, porque quiero la respuesta completa para otras cosas.

Aquí está un ejemplo:

const MyComponent = () => {

  const [calledObj, setCalledObj] = useState({})

  useEffect(() => {
    //Calling API here and setting object response as calledObj State
    setCalledObj(apiResponse)
  }, []);

  //This will throw an error when the API response has not been sent back yet.//
  // While this would be easy to write the whole path in the return, the actual path is really long.//
  const { name } = calledObj.person

  return (<div>{name}</div>)
}

¿Dónde puedo desestructurar o cómo puedo solucionar esto?

1
Chris Scott 27 feb. 2021 a las 02:42

3 respuestas

La mejor respuesta

Puede utilizar encadenamiento opcional y / o el anular el operador coelescente para solucionarlo .

Nota: IE no admite ni de estos, pero babel los rellenará.

const { name } = calledObj?.person ?? {};
  1. El encadenamiento opcional (el ?. en calledObj?.person) evita que explote si calledObj no está definido.
  2. El operador de fusión nula (??) devuelve {} si calledObj.person no está allí.

Con esta combinación, el lado derecho está garantizado para evaluar un objeto, por lo que la desestructuración del lado izquierdo nunca explota.

let calledObject; // undefined;

// name is undefined, but it doesn't blow up.
const { name: name1 } = calledObject?.person ?? {};

console.log(`name 1: ${name1}`); // name 1: undefined

// ----------------

// now it's an object, but doesn't have a person property
calledObject = {};

// name is still undefined, still doesn't blow up.
const { name: name2 } = calledObject?.person ?? {};

console.log(`name 2: ${name2}`); // name 1: undefined

// ----------------

// with person.name present…
calledObject.person = { name: 'joe' };

const { name: name3 } = calledObject?.person ?? {};

// …it works as you'd expect
console.log(`name 3: ${name3}`); // name 3: 'joe'
3
ray hatfield 26 feb. 2021 a las 23:59

Dependiendo de lo que desee que su variable name tenga por defecto en el primer renderizado, supongo que podría hacer algo como esto:

  const { name } = calledObj.person ? calledObj.person : {name: ''}
0
codemonkey 26 feb. 2021 a las 23:50

Puede inicializar su estado con const [calledObj, setCalledObj] = useState ({person: {}})

Y esto pondrá indefinido en 'nombre' pero no está rompiendo su código.

0
Soli Huayhua 27 feb. 2021 a las 00:01