Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReactJS SetState not rerendering

I have:

JobScreen

handleSetView(mode, e) {
        this.setState({
            view: mode
        });
        console.log(this.state.view)
    }

    render() {
        return (

            <div className="jobs-screen">
                <div className="col-xs-12 col-sm-10 job-list"><JobList view={this.state.view} /></div>
                <div className="col-xs-12 col-sm-2 panel-container">
                    <div className="right-panel pull-right"><RightPanel handleSetView={this.handleSetView} /></div>
...
)
}

RightPanel

render() {
        return (
            <div>
                <div className="controls">
                    <span className="title">Views <img src="images\ajax-loader-bar.gif" width="24" id="loader" className={this.state.loading ? "pull-right fadeIn" : "pull-right fadeOut"}/></span>
                    <button onClick={this.props.handleSetView.bind(this, 'expanded')}><img src="/images/icons/32px/libreoffice.png" /></button>
                    <button onClick={this.props.handleSetView.bind(this, 'condensed')}><img src="/images/icons/32px/stack.png" /></button>
                    </div>
...
)}

JobList

render() {
        var jobs = [];
        this.state.jobs.forEach((job) => {
            jobs.push(
                <Job key={job.id} job={job} view={this.props.view} loading={this.state.loading} toggleTraderModal={this.props.toggleTraderModal} toggleOFTModal={this.props.toggleOFTModal}/>
            );
        });

        return (
            <div>
                {jobs}
            </div>
        );
    };

The problem is, is that the changing of the view state does not rerender any of the child elements.

How can I get this to work?

like image 337
imperium2335 Avatar asked May 13 '16 08:05

imperium2335


People also ask

Why does setState not update immediately?

setState function or the updater function returned by the React. useState() Hook in class and function components, respectively. State updates in React are asynchronous; when an update is requested, there is no guarantee that the updates will be made immediately.

Does setState cause re-render?

Method 1 (by changing props): If we pass the state of the parent component as a prop to the child and call setState on the parent, it will cause the re-render of the child component as its props are changed.

Why putting setState () in render () is not preferred?

The render() function should be pure, meaning that it does not modify a component's state. It returns the same result each time it's invoked, and it does not directly interact with the browser. In this case, avoid using setState() here.

How do you're-render after setState?

If we want to re-render the component then we can easily do so by calling the setState() function which is obtained by destructuring the array returned as a result of calling the useState() hook. Whenever we update the state using the setState() method it re-renders the current component and its child components.


1 Answers

Not sure if it is the core of your problem, but:

handleSetView={this.handleSetView}

is wrong, because how js binds this. Use:

handleSetView={this.handleSetView.bind(this)}

instead.

Also,

this.setState({
  view: mode
});
console.log(this.state.view)

seems strange; note that this.state is not modified right after you call setState, it may took some time while React dispatches the scheduled setState operation. Put that console.log into render to see when it is actually called.

Finally, make sure, your components do not implement shouldComponentUpdate lifecycle method (you are probably not doing this explicitly, but if your component extends some class other than React.Component this may happen)

like image 100
Tomas Kulich Avatar answered Oct 22 '22 18:10

Tomas Kulich