1

Most examples shows ReactJS fetch() in componentDidMount. In my example, I need a fetch as part of a state change received from another component, after initialization (initially my component is empty). I currently do it in render() which is always called on a state change.

But something's wrong: the Fetch works and the render() is called on the state change, but return <div>..</div> doesn't output, so I don't see my rendered HTML.

Component

componentDidMount() {   
    /* Nothing here. The component should initially be empty. */    
}   

render() {
    
    const { study, items } = this.props;
    
    // THIS WORKS Another component triggers this one's state change, I get the alert
    alert('State changed: ' + study);
    
    if (study) {
        /* Ajax call in render(). The fetch works as verified with console.log(result) */
        fetch("/api/myCall?id=" + study)
        .then(res => res.json())
        .then(
            (result) => {
                            return <div>RESULT OBTAINED</div>  <-- THIS DOESN'T WORK, result is OK
                        },
            (error)  => {
                            return <div>ERROR</div>
                        }
            );              
    } else {
        return <div>EMPTY</div>
    }
3
  • 2
    Dont do API requests in render(). Populate state after results are received by fetch and use state variable in render. Commented Mar 4, 2021 at 17:00
  • But who does the fetch? The parent component? and where? Commented Mar 4, 2021 at 17:15
  • 1
    Whatever goes inside .then(... is asynchronous. Small wonder you don't see anything. You need to update a state variable with those results and let the component re-render to see anything. Commented Mar 4, 2021 at 17:41

1 Answer 1

2

For this to work you would have to block the rendering until the fetch is fullfilled, or manipulate the state of your component depending on the result/error, which in turn would cause another render and with it another fetch call so you would get an endless loop. So calling fetch directly inside render is never a good idea if your UI depends on the result.

Instead, use componentDidUpdate(), like this:

componentDidUpdate(prevProps) {
   const { study } = this.props;

   if(prevProps.study !== study){
       fetch("/api/myCall?id=" + study).then(result => {
           //Manipulate your state here!
       })
   }

}

This way you only request new data and update your components state when the study property, which is passed from outside, changes. No need to call fetch inside of render.

-- EDIT --

Alternatively you could also do the fetch in the other component and pass all the data you need via props to your component. That way you would have a stateless component which is easier to maintain.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.