【问题标题】:How can i merge two state into single state in React Hooks?如何在 React Hooks 中将两个状态合并为单个状态?
【发布时间】:2020-07-03 14:03:26
【问题描述】:

我想合并两个名为 Data 和 District 值的状态并创建一个名为 test 的单个状态。因为我从不同的 API 获取两个状态值。我无法使单个状态合并以下状态的数据,我尝试了但是当我尝试合并两个状态值时,我得到一个状态值但无法获得下一个状态值,因为我尝试使用扩展运算符但仍然无法解决问题。以下是我的代码:请帮助解决:

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

export default function Testmap() {
const [Data, setData] = useState([]);//fetched data
const [isLoading, setIsloading] = useState(true);
const [District, setDistrict] = useState([]);
const [test, setTest] = useState({
    data: [],
    districts: []
});





useEffect(() => {
    //fetching data from api 
    Axios.get('https://covid19wst.yilab.org.np/api/v1/form')
        
        .then(res => {
            setData(res.data)
            setTest({ ...test, data: res.data })
            setIsloading(false)

        })
        .catch(err => {
            console.log(err);
        })
    Axios.get('https://bipad.gov.np/api/v1/district/')
        .then(res => {
            setDistrict(res.data.results)
            setTest({ ...test, districts: res.data.results })



            setIsloading(false)

        })
        .catch(err => {
            console.log(err);
        })

}, [])




console.log(isLoading);
console.log("data", Data);
console.log("districts>>", District);
console.log("test>>>", test);

return (
    <div>
        <h2>Hello</h2>
    </div>
)
  }

以下是我的输出:

在上面的输出中,我尝试在单个状态测试中保留数据和区域的两个状态值,但是当代码运行时,当我使用扩展运算符保留先前值时,我无法使用先前值获取更新值。仍然是先前的值没有保存,请问如何解决?请帮忙。

【问题讨论】:

    标签: javascript arrays reactjs rxjs frontend


    【解决方案1】:

    Promise.all() 是处理多个互不依赖的请求的更好选择。

    考虑仅在两个请求都完成时将loading 设置为false

    另外,状态可以这样简化:

    export default function Testmap() {
      const [isLoading, setIsloading] = useState(false);
      const [test, setTest] = useState({
        data: [],
        districts: [],
      });
    
      useEffect(() => {
        setIsloading(true);
    
        Promise.all([
          Axios.get("https://covid19wst.yilab.org.np/api/v1/form"),
          Axios.get("https://bipad.gov.np/api/v1/district/"),
        ])
          .then((results) => {
            setIsloading(false);
            setTest({
              data: results[0].data,
              districts: results[1].data.results
            });
          })
          .catch((err) => {
            setIsloading(false);
            console.log(err);
          });
      }, []);
    
      return (
        <div>
          <h2>Hello</h2>
        </div>
      );
    }
    

    【讨论】:

      【解决方案2】:

      我建议在 2 个useEffect hooks 中做:

      1. 第一个将运行一次并将数据提取到您的districtsdata 状态。
      2. 第二个将在依赖数组中包含districtsdata,因此每次datadistricts 更改时都会运行。
      import React, {useState, useEffect} from 'react';
      import Axios from 'axios';
      
      export default function Testmap() {
          const [data, setData] = useState([]);//fetched data
          const [isLoading, setIsloading] = useState(true);
          const [districts, setDistricts] = useState([]);
          const [test, setTest] = useState({
              data: [],
              districts: []
          });
      
          useEffect(() => {
              //fetching data from api
              Axios.get('https://covid19wst.yilab.org.np/api/v1/form')
                  .then(res => {
                      setData(res.data);
                      setIsloading(false);
                  })
                  .catch(err => {
                      console.log(err);
                  });
              Axios.get('https://bipad.gov.np/api/v1/district/')
                  .then(res => {
                      setDistricts(res.data.results);
                      setIsloading(false);
                  })
                  .catch(err => {
                      console.log(err);
                  });
      
          }, []);
      
          useEffect(() => {
              setTest({...test, data, districts});
          }, [data, districts]);
      
          return (
              <div>
                  <h2>Hello</h2>
              </div>
          );
      }
      

      【讨论】:

        【解决方案3】:

        来自 Axios 文档“执行多个并发请求”

        function getUserAccount() {
          return axios.get('/user/12345');
        }
        
        function getUserPermissions() {
          return axios.get('/user/12345/permissions');
        }
        
        Promise.all([getUserAccount(), getUserPermissions()])
          .then(function (results) {
            const acct = results[0];
            const perm = results[1];
          });
        
        

        【讨论】:

          【解决方案4】:

          我认为你可以使这两个http请求都asycn这样,然后你可以改变一次变量测试状态,像这样:

          //fetching data from api 
          const fetchDataFromApi = async () => {
              let dataResponse = []
              await Axios.get('https://covid19wst.yilab.org.np/api/v1/form')
                  
                  .then(res => {
                      setData(res.data)
                      dataResponse = res.data
                      setIsloading(false)
          
                  })
                  .catch(err => {
                      console.log(err);
                  })
              let districtResponse = []
              await Axios.get('https://bipad.gov.np/api/v1/district/')
                  .then(res => {
                      setDistrict(res.data.results)
                      districtResponse = res.data.results
                      setIsloading(false)
          
                  })
                  .catch(err => {
                      console.log(err);
                  })
          
                 setTest([...test, ...dataResponse, ...districtResponse])
              }
          

          【讨论】:

            最近更新 更多