在渲染之前等待 react-promise 解决

IT技术 javascript reactjs
2021-05-18 16:44:00

所以我有大量的数据可以从 API 中检索。我认为问题在于我的组件在从Promise接收数据之前调用了 renderMarkers 函数。

所以我想知道如何在调用我的 renderMarkers 函数之前等待Promise完全解析数据?

class Map extends Component {

componentDidMount() {
  console.log(this.props)
  new google.maps.Map(this.refs.map, {
    zoom: 12,
    center: {
      lat: this.props.route.lat,
      lng: this.props.route.lng
    }
  })
}

componentWillMount() {
  this.props.fetchWells()
}

renderMarkers() {
  return this.props.wells.map((wells) => {
    console.log(wells)
  })
}

render() {
  return (
    <div id="map" ref="map">
      {this.renderMarkers()}
    </div>
  )
 }
} 

function mapStateToProps(state) {
  return { wells: state.wells.all };
}

export default connect(mapStateToProps, { fetchWells })(Map);
4个回答

在获取所有信息之前,您可以执行以下操作来显示Loader

class Map extends Component {
  constructor () {
    super()
    this.state = { wells: [] }
  }

  componentDidMount() {
    this.props.fetchWells()
      .then(res => this.setState({ wells: res.wells }) )
  }

  render () {
    const { wells } = this.state
    return wells.length ? this.renderWells() : (
      <span>Loading wells...</span>
    )
  }
}

在 API 调用完成之前调用渲染函数是可以的。wells是一个空数组(初始状态),您只需渲染任何内容。并且在从 API 接收到数据后,你的组件会因为 props(redux store)的更新而自动重新渲染。所以我看不出问题。

如果你真的想在接收 API 数据之前阻止它渲染,只需在你的渲染函数中检查,例如:

if (this.props.wells.length === 0) {
  return null
}

return (
  <div id="map" ref="map">
    {this.renderMarkers()}
  </div>
)

对于带钩子的功能组件:

    function App() {
        
          const [nodes, setNodes] = useState({});
          const [isLoading, setLoading] = useState(true);
        
          useEffect(() => {
            getAllNodes();
          }, []);
        
          const getAllNodes = () => {
            axios.get("http://localhost:5001/").then((response) => {
              setNodes(response.data);
              setLoading(false);
            });
          };
        
        
          if (isLoading) {
            return <div className="App">Loading...</div>;
          }
          return (
            <>
              <Container allNodes={nodes} />
            </>
        
          );
}

所以我有类似的问题,我自己做出react并找到了解决方案。通过使用 Async/Await 调用 react 代码片段如下,请试试这个。

 import Loader from 'react-loader-spinner'

 constructor(props){
    super(props);
    this.state = {loading : true}
  }
  getdata = async (data) => {
    return await data; 
  }
  getprops  = async (data) =>{
    if (await this.getdata(data)){
      this.setState({loading: false})
    }
  }
  render() {
  var { userInfo , userData} = this.props;
    if(this.state.loading == true){
      this.getprops(this.props.userData);
    } 
    else{
//perform action after getting value in props
    }
    return (
      <div>
      {
           this.state.loading ? 
             <Loader
               type="Puff"
               color="#00BFFF"
               height={100}
               width={100}
             />
           :    
              <MyCustomComponent/> // place your react component here
      }
      </div>
      )
}