简体   繁体   中英

Wait for react-promise to resolve before render

So I have a large set of data that I'm retrieving from an API. I believe the problem is that my component is calling the renderMarkers function before the data is received from the promise.

So I am wondering how I can wait for the promise to resolve the data completely before calling my renderMarkers function?

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

You could do something like this to show a Loader until all the info is fetched:

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>
    )
  }
}

for functional components with hooks:

    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} />
            </>
        
          );
}

Calling the render function before the API call is finished is fine. The wells is an empty array (initial state), you simply render nothing. And after receiving the data from API, your component will automatically re-render because the update of props (redux store). So I don't see the problem.

If you really want to prevent it from rendering before receiving API data, just check that in your render function, for example:

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

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

So I have the similar problem, with react and found out solution on my own. by using Async/Await calling react Code snippet is below please try this.

 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>
      )
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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