János
János

Reputation: 35038

Why state not get reset in React component?

This is the method, you can see many set to undefined lines, but they does not work.

  handleDismissMenuAndLogOut = () => {
    this.setState({
      buyOrRelease: "buy",
      anchorEl: undefined,
      isLoggedIn: undefined,
      userID: undefined,
      name: undefined,
      email: undefined,
      picture: undefined
    }, this.props.userLoginAndDataDownloadCompletedOut(this.state));
  };

And you can see, values are not reset:

enter image description here

I am debugging, but it does not reset the values, why? Am I miss something? HEre the whole class:

import React from "react";
import Button from "@material-ui/core/Button";
import FacebookLogin from "react-facebook-login";
import Menu from "@material-ui/core/Menu";
import MenuItem from "@material-ui/core/MenuItem";
import AppBar from "@material-ui/core/AppBar";
import Toolbar from "@material-ui/core/Toolbar";
import Typography from "@material-ui/core/Typography";
import { withStyles } from "@material-ui/core/styles";
import axios from "axios";

const styles = theme => ({
  title: {
    flexGrow: 1
  }
});

class BarAndMenu extends React.Component {
  constructor() {
    super();
    this.state = {
      isLoggedIn: false,
      name: "",
      buyOrRelease: "buy",
      anchorEl: undefined,
      userID: undefined,
      email: undefined,
      picture: undefined
    };
  }

  responseFacebook = response => {
    this.setState({
      accessToken: response.accessToken,
      isLoggedIn: true,
      userID: response.userID,
      name: response.name,
      email: response.email,
      picture: response.picture.data.url
    });
    let accessToken = response.accessToken;
    axios
      .get(
        "https://graph.facebook.com/v5.0/me/accounts?fields=id,name&access_token=" +
          response.accessToken
      )
      .then(async pagesResponse => {
        let promisesArray = pagesResponse.data.data.map(async page => {
          return axios
            .get(
              "https://graph.facebook.com/v5.0/" +
                page.id +
                "/events?fields=id,name&access_token=" +
                accessToken
            )
            .catch(e => e);
        });
        const responses = await Promise.all(promisesArray);
        var pages = [];
        responses.forEach((response, i) => {
          const page = pagesResponse.data.data[i];
          pages.push({
            id: page.id,
            name: page.name,
            events: response.data.data
          });
        });
        let url =
          "https://ticket-44-be.herokuapp.com/fetchStatusOfManagedReleases";
        axios({
          method: "post",
          url: url,
          data: pages,
          headers: { "Content-Type": "application/json", crossDomain: true }
        })
          .then(response => {
            this.setState({
              pages: response.data
            }, this.userLoginAndDataDownloadCompletedIn);
          })
          .catch(function(error) {
            console.log(error);
          });
      });
  };

  userLoginAndDataDownloadCompletedIn() {
    this.props.userLoginAndDataDownloadCompletedOut(this.state);
  }

  handleMenuClick = event =>
    this.setState({
      anchorEl: event.currentTarget
    });

  handleDismissMenu = () => {
    this.setState({ anchorEl: undefined });
  };

  handleDismissMenuAndLogOut = () => {
    this.setState({
      buyOrRelease: "buy",
      anchorEl: undefined,
      isLoggedIn: undefined,
      userID: undefined,
      name: undefined,
      email: undefined,
      picture: undefined
    }, this.props.userLoginAndDataDownloadCompletedOut(this.state));
  };

  switchToRelease = () => {
    this.setState({ buyOrRelease: "release" }, this.buyOrReleaseModeChangedIn);
  };

  switchToBuy = () => {
    this.setState({ buyOrRelease: "buy" }, this.buyOrReleaseModeChangedIn);
  };

  buyOrReleaseModeChangedIn() {
    this.props.buyOrReleaseModeChangedOut(this.state);
  }

  render() {
    let fbContent;
    if (this.state.isLoggedIn) {
      let menuItemBuyOrRelease;
      if (this.state.buyOrRelease === "release") {
        menuItemBuyOrRelease = (
          <MenuItem onClick={this.switchToBuy}>Switch Buy mode</MenuItem>
        );
      } else {
        menuItemBuyOrRelease = (
          <MenuItem onClick={this.switchToRelease}>
            Switch Release mode
          </MenuItem>
        );
      }
      fbContent = (
        <div>
          <Button
            aria-controls="simple-menu"
            aria-haspopup="true"
            onClick={this.handleMenuClick}
          >
            {this.state.name}
          </Button>
          <Menu
            id="simple-menu"
            anchorEl={this.state.anchorEl}
            keepMounted
            open={Boolean(this.state.anchorEl)}
            onClose={this.handleDismissMenu}
          >
            <MenuItem onClick={this.handleDismissMenuAndLogOut}>
              Log out
            </MenuItem>
            {menuItemBuyOrRelease}
            <MenuItem>My tickets</MenuItem>
          </Menu>
        </div>
      );
    } else {
      let fbAppId;
      if (window.location.hostname === "localhost") fbAppId = "402670860613108";
      else fbAppId = "2526636684068727";
      fbContent = (
        <FacebookLogin
          appId={fbAppId}
          autoLoad={true}
          fields="name,email,picture"
          onClick={this.componentClicked}
          callback={this.responseFacebook}
        />
      );
    }

    return (
      <AppBar position="static">
        <Toolbar>
          <Typography variant="h6" className={this.props.classes.title}>
            Tiket.hu
          </Typography>
          <Button color="inherit">Search</Button>
          <Button color="inherit">Basket</Button>
          {fbContent}
        </Toolbar>
      </AppBar>
    );
  }
}

export default withStyles(styles)(BarAndMenu);

Upvotes: 0

Views: 814

Answers (1)

Francis Malloch
Francis Malloch

Reputation: 1094

setState is async, meaning that the code running directly after the setState function will not have access to the new state. You have to use the second parameter of setState to access the new state.

  this.setState({
      isLoggedIn: false,
      name: "",
      buyOrRelease: "buy",
      anchorEl: undefined,
      isLoggedIn: undefined,
      userID: undefined,
      name: undefined,
      email: undefined,
      picture: undefined
  }, this.props.userLoginAndDataDownloadCompletedOut);

  this.setState({
      key: value,
      // This new state is shallow merged with the old one, if you dont specify an existing key, the existing key and value will remain the same.
  }, (newState) => {
      newState.key === value; // newState contains the new complete state.
  });

Upvotes: 4

Related Questions