【问题标题】:React hook useEffect returns empty array at firstReact hook useEffect 首先返回空数组
【发布时间】:2021-03-04 06:18:06
【问题描述】:

我像这样从我的数据库中获取数据:

 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() 都显示空数组。在第二次单击后,它们开始工作并显示阵列。我猜我需要以更好的方式更新它们,但不知道如何。 (我正在尝试显示数据,但在第一次单击按钮时实际上什么也没显示)。

【问题讨论】:

  • 标题中不要大喊大叫
  • 编辑删除大喊大叫。

标签: javascript reactjs react-hooks use-effect


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    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]);
    
    

    所以在您的情况下,您可以检查 list 和 employees 是否不为空,如果返回 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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-09
      • 2020-07-16
      • 1970-01-01
      • 2019-10-08
      • 2021-07-24
      • 2022-06-12
      • 2021-10-28
      • 2021-09-24
      相关资源
      最近更新 更多