首页 > 解决方案 > 当我使用 useEffect 从 API 获取对象时,无法将 json obj 存储在状态中

问题描述

我试图在模式上显示对象的属性,但在我获取它之后似乎什么都没有发生。我试过不使用 useEffect 钩子,它确实存储了项目,但是我无法访问属性,我询问了它,并且用户告诉我使用 use Effect。但是现在,似乎什么都没有存储...

这是我的代码:

  import React, {useState, useEffect } from 'react';

const Modal = ({ handleClose, show, id }) => {
    const showHideClassName = show ? "mod displayBlock" : "mod displayNone";
    const [peliSeleccionada, setPeli] = useState([]);

    useEffect(() => {
        fetch(`http://localhost/APIpeliculas/api/pelicula/read_single.php/?ID=${id}`)
            .then(res => res.json())
            .then(
                result => {
                    alert(result); //the alerts dont even pop up
                    setPeli(result);
                    alert(peliSeleccionada);
                });
    }, []);
    
    return (
      <div className={showHideClassName}>
        <section className="mod-main">
            <h5>EDITAR: </h5>
            <label> 
                { peliSeleccionada.Nombre } 
            </label>
            <div className="btn-grupo">
                <button type="button" className="btn btn-success btn-lg btn-block">Guardar cambios</button>
                <button onClick={handleClose} type="button" className="btn btn-secondary btn-lg btn-block">Cerrar</button>
            </div>
        </section>
      </div>
    );
};

export default Modal;

我在 useEffect 函数中放置的警报甚至没有弹出,而且我在进入页面后也会在控制台上收到此错误:

Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0

我还想访问我的对象的属性,它们是:ID、Nombre、Categoria 和 Director。这是正确的方法吗?{ peliSeleccionada.Nombre }

标签: jsonreactjsstate

解决方案


useEffect在组件渲染后运行,类似于componentDidMount工作方式。这意味着,简单地说,组件将return触发 fetch。

您的状态存在问题,peliSeleccionada您将其声明为一个数组,但peliSeleccionada.Nombre如果它是一个对象则调用它。这意味着在第一次渲染时,它将undefinedpeliSeleccionada.Nombre.

实现这一点的一种方法是将其与loading状态配对。

const Modal = () => {
  const [loaded, setLoading] = useState(true);
  const [peliSeleccionada, setPeli] = useState({});

  useEffect( () => {
    fetch()
     .then(res => { 
       setPeli(res) // parse this accordingly
     }) // or chain of thens if needed
     .catch(err => {
       setLoading(false);
       console.log(err) // something failed in the fetch. You could have another state to mark that the fetching failed; close the modal, show an error, etc.
     })
  }, [])

  if(!loaded) return 'Loading...'

  return (<div>Data goes here</div>) // be careful if the fetch failed, it won't show data!

}

最后但并非最不重要的一点是,错误发生在 fetch 中,并且消息准确地指出,您没有捕获它。如果它在fetch调用中,则上面的代码有效。如果它在解析中,它可能需要try/catch围绕useEffect


推荐阅读