繁体   English   中英

React hook useEffect 首先返回空数组

[英]React hook useEffect returns empty array at first

我从我的数据库中获取数据,如下所示:

 const clicked = props.clicked;
 const [allEmployees, setAllEmployees] = useState([]);
 const [list, setList] = useState([]);

 useEffect(()=>{       //getting employees
   Axios.get(
     PATH + `/${employees}`
   ).then((data) => {
     setAllEmployees(data.data);
   });
 },[]);

useEffect(()=>{        //getting list of employees who should be selected
   Axios.get(
     PATH + `/${list}`
   ).then((data) => {
     setList(data.data);

     setList(
       allEmployees.map(t=>{
         if(list.includes(t.id)){
           return{
             select: true,
             id: t.id,
             name: t.name
           }
         }else{
           return{
             select: false,
             id: t.id,
             name: t.name
           }
         }
       })
     )
     console.log(allEmployees);// <<
     console.log(list);//  <<
   });
 },[clicked]);

我的问题是我第一次点击按钮,激活clicked.props ,两个console.log() 都显示空数组。 在第二次点击之后,它们开始工作并显示数组。 我猜我需要以更好的方式更新它们,但不知道如何。 (我正在尝试显示数据,但在第一次单击按钮时它确实没有显示任何内容)。

这是因为它们一开始实际上是空数组。 Axios 向服务器发送异步请求,获取数据。 状态钩子在第一页渲染后立即渲染,所以基本上是在同一时间。 来自服务器的数据将在返回时返回。 (因为这是一个承诺)。 一旦数据作为承诺返回,您可以解析它并将解析的数据添加到状态。

似乎您还试图在第二个 useEffect 中使用不同的数据两次设置列表状态。 您首先使用从 axios 获取的数据,然后使用 (allEmployees) 之后的第一个 useEffect 中的数据,我很难真正理解您在这里的思维过程。

第一次单击时 console.logs 返回空的原因是因为 useState 的工作方式,当您设置 state 时,您必须等到组件重新加载才能看到 state 的新值。 因此,当您第一次单击状态为空时,您会获得空日志,但是在第二次单击时,您不会获得任何空值,但实际上它们只是您第一次单击时的新值:

const [value,setValue] = useState(0)
useEffect(()=>{        //getting list of employees who should be selected
   Axios.get(PATH + `/${list}` )
   .then((data) => {
     setValue(value+1  )
   });
  console.log(value);//this will output 1 
 },[]);

useEffect(()=>{        //getting list of employees who should be selected
    console.log(value);//this will output 2 on the next component render 
},[value]);

因此,在您的情况下,您可以检查列表和员工是否为空,如果是,则返回 null :

 const clicked = props.clicked;
 const [allEmployees, setAllEmployees] = useState([]);
 const [list, setList] = useState([]);

 useEffect(()=>{       //getting employees
   Axios.get(
     PATH + `/${employees}`
   ).then((data) => {
     setAllEmployees(data.data);
   });
 },[]);

useEffect(()=>{        //getting list of employees who should be selected
   Axios.get(
     PATH + `/${list}`
   ).then((data) => {
     setList(
       allEmployees.map(t=>{
         if(list.includes(t.id)){
           return{
             select: true,
             id: t.id,
             name: t.name
           }
         }else{
           return{
             select: false,
             id: t.id,
             name: t.name
           }
         }
       })
     )
     console.log(allEmployees);// <<
     console.log(list);//  <<
   });
 },[clicked]);


 if(!allEmployees.length ||  !list.length) return null 
 // after this line you're garanted that allEmployees and list are not empty 
 render <div>{list.map(your implemntation)}<div>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM