在两次 axios api get 请求之后设置状态之前反应渲染

React rendering before state set after two axios api get requests

我正在尝试通过 axios 进行两次调用,等待这些响应,使用 useState 设置相应的变量,将 isLoading 设置为 false,然后呈现我的 React 应用程序。在应用程序尝试呈现之前,我无法加载 fleets。当 fleets 仍然为 null 时,应用会尝试呈现,从而导致 TypeError: Cannot read property 'map' of null。解决此问题的最佳方法是什么?为什么我的 .then 链不工作?

import './App.css';
import React, { useState, useEffect } from 'react';
import axios from 'axios';

function App() {

  const DEFAULT_FLEET = "My Fleet"
  const [selectedFleet, setSelectedFleet] = useState(DEFAULT_FLEET);
  const [contracts, setContracts] = useState(null);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(null);
  const [fleets, setFleets] = useState(null);

  useEffect(() => {
    Promise.all([
      axios.get('/fleets'),
      axios.get('/contracts?fleet_name=' + selectedFleet)
    ])
    .then(([fleetsResponse, contractsReponse]) => {
      setFleets(fleetsResponse.data);
      setContracts(contractsReponse.data);
    })
    .catch(error => {
      console.log(error);
      setError(error.message)
    })
    .then(console.log(fleets))
    .then(setIsLoading(false))
    
  }, [])

  if (error) {
    return (<>Error: { error }</>)
  } else if (isLoading) {
    return (<div>Is Loading...</div>)
  } else {

    const fleetOptions = fleets.map((fleet) => {
      <option value={fleet.name}> {fleet.name} </option>
    });

  return (
    <div className="App">
      <select>
        {fleetOptions}
        </select>
      <div>{ contracts }</div>
    </div>
  );
  }
}

export default App;

大功告成,then 的参数应该是一个函数,当 promise 实现时将被调用。在您的代码中, setIsLoading(false) 在承诺仍在获取时执行。尝试更改:

-    .then(setIsLoading(false))
+    .then(() => setIsLoading(false))