简体   繁体   中英

Why react doesn't call render when state is changed?

I have problem with automatically re-rendering view, when state is changed. State has been changed, but render() is not called. But when I call this.forceUpdate() , everything is ok, but I think that's not the best solution. Can someone help me with that ?

class TODOItems extends React.Component {

constructor() {
    super();

    this.loadItems();
}

loadItems() {
    this.state = {
        todos: Store.getItems()
    };
}

componentDidMount(){
    //this loads new items to this.state.todos, but render() is not called
    Store.addChangeListener(() => { this.loadItems(); this.forceUpdate(); });
}

componentWillUnmount(){
    Store.removeChangeListener(() => { this.loadItems(); });
}

render() {

    console.log("data changed, re-render");
    //...
}}

You should be using this.state = {}; (like in your loadItems() method) from the constructor when you are declaring the initial state. When you want to update the items, use this.setState({}) . For example:

constructor() {
    super();

    this.state = {
        todos: Store.getItems()
    };
}

reloadItems() {
    this.setState({
        todos: Store.getItems()
    });
}

and update your componentDidMount :

Store.addChangeListener(() => { this.reloadItems(); });

You sholdn't mutate this.state directly. You should use this.setState method.

Change loadItems :

loadItems() {
    this.setState({
        todos: Store.getItems()
    });
}

More in react docs

In your component, whenever you directly manipulate state you need to use the following:

this.setState({});

Complete code:

class TODOItems extends React.Component {

constructor() {
    super();

    this.loadItems();
}

loadItems() {
  let newState = Store.getItems();
    this.setState = {

        todos: newState
    };
}

componentDidMount(){
    //this loads new items to this.state.todos, but render() is not called
    Store.addChangeListener(() => { this.loadItems(); this.forceUpdate(); });
}

componentWillUnmount(){
    Store.removeChangeListener(() => { this.loadItems(); });
}

render() {

    console.log("data changed, re-render");
    //...
}}

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