简体   繁体   中英

React - component state not being set

Why is the output of the piece of code below "true"?

class InstagramGallery extends React.Component {

    constructor(props) {
        super(props);

        this.state = {
            images: true
        };
    }

    componentDidMount() {
        var accessToken = '*Instagram token*';
        var instagramApi = new Instagram(accessToken);
        instagramApi.userSelfMedia().then(function(result) {
            this.setState({
                images: false,
            });
        }, function(err) {
            console.log(err);
        });

    }

    render() {
        console.log(this.state.images); 
        return (
            <div className="instagram-gallery">

            </div>
        )
    }
}

From what I know, the constructor is being called first. Therefore images=true , after that it renders with console.log(true) , and componentDidMount is called. After data from instagram is fetched, and I update component state which should re-render the component with images=false . Where am I wrong?

You are using a regular function for instagramAp.userSelfMedia callback hence losing this context. Use an arrow function instead:

instagramApi.userSelfMedia().then(
  result => {
    this.setState({
      images: false
    });
  },
  function(err) {
    console.log(err);
  }
);

Regular functions create their own lexical scope, so this does not point your class in the callback function. Arrow functions don't create their own lexical scopes, to this points your component and you can use this.setState() .

Using an arrow function saves you from binding your function or keeping this in another variable like:

var accessToken = "*Instagram token*";
var instagramApi = new Instagram(accessToken);
const that = this;
instagramApi.userSelfMedia().then(
  function(result) {
    that.setState({
      images: false
    });
  },
  function(err) {
    console.log(err);
  }
);

I've not been using RN for that long but does this have an affect?

componentDidMount() {
    var accessToken = '*Instagram token*';
    var instagramApi = new Instagram(accessToken);
    instagramApi.userSelfMedia().then((result) => { //USING ARROW FUNCTION
        this.setState({
            images: false,
        });
    }, function(err) {
        console.log(err);
    });

}

I added an arrow function so that the 'this.state' doesn't get mixed up with the 'this' inside instagramApi.userSelfMedia().

Because this isn't available

Use arrow function

 instagramApi.userSelfMedia().then((result) => {
        this.setState({
            images: false,
        });
    }, function(err) {
        console.log(err);
    });

  }

Or bind it manually

  instagramApi.userSelfMedia().then(function(result) {
        this.setState({
            images: false,
        });
    }.bind(this), function(err) {
        console.log(err);
    });

  }

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