Search code examples
javascriptreactjstwitter-bootstrapjsxvirtual-dom

ReactJS cannot seem to call function after page load


I need to be able update button class styles after page loads. Tried doing it in Render() and i have seen people talk about setTimeout and setInterval, but this other way with event is working part of the time

  1. ComponentDidMount makes a axios web api call grabs data and in a map all is in render. I need to check local storage and such, and want to update button color and text, so I tried many things, but then tried window.addeventlistener ... this.handleload

Seems to work only part of the time.... its like it is happening TOO FAST, I don't want to add "hack" like timers, but i'm stuck with no idea how to do this.

I tried calling functions in the render as well. Not sure why this is so hard to do.

handleLoad() {
    alert('always runs from outside loop');

    // loop ONLY runs after refreshing browser several times
    for (var i = 0; i < this.state.data.length; i++) {
       //rarely makes it in 
       alert('made it');
       document.getElementById("4534552").classList.remove('btn-warning');
    }
 }

componentDidMount() {

     webApi.get('sai/getofflinemembers?userId=N634806')
            .then((event) => { 
            //........
    }


    // THIS is what i call 
    window.addEventListener('load', this.handleLoad);

}



render() {

    const contents = this.state.data.map(item => (
        <button id={item.Member_ID} type="button" onClick={(e) => this.downloadUser(item.Member_ID,e)} 
              className="btn btn-warning">Ready for Download</button>
    )
}

I just need to call a function and loop over all the DOM and change it as needed. Now that has me thinking about react creating a virtual DOM to which i don't know.

Needing to check local storage if a member is already set, then set the class of a bootstrap button to a specific color and text as well.

Thoughts?


Solution

  • Just an advice: If you want to manipulate the DOM, it's better to use refs instead of using document.getElementById. https://reactjs.org/docs/glossary.html#refs

    But your problem can be solved by using state to store the css class:

    class SomeComponent extends React.Component {
    
      state = {
        buttonCSSClass: 'btn btn-warning',
      }
    
      componentDidMount() {
            webApi.get('sai/getofflinemembers?userId=N634806')
                .then((event) => {})
                .then(() => this.setState({buttonCSSClass: 'btn'})) // it will update the css class
            }
      }
    
      render() {
        const { data, buttonCSSClass } = this.state
        return data.map(item => (
          <button
            key={item.Member_ID}
            id={item.Member_ID}
            type="button"
            onClick={e => this.downloadUser(item.Member_ID, e)}
            className={buttonCSSClass} 
          >
            Ready for Download
          </button>
        ))
      }
    }