Jhig85
Jhig85

Reputation: 355

setState() not mutating state immediately

I have a parent component that uses a get request to retrieve a JWT Token and then passes that token as a prop down to a child component. That token gets passed in another get request to authorize and retrieve data. On the method that does that get request, I am using setState after the request is successful to update the state of an empty array. The problem is that it is lagging behind due to setState not mutating the state quickly enough and the array is staying empty. I am trying to pass that array value as a prop to a child component. Any help is appreciated.

App.js - Parent Component

class App extends Component {
 constructor(props) {
    super(props);

    this.state = {
      token: '',
    };

    this.getToken = this.getToken.bind(this);
  }

  getToken() {
    fetch('https://login-cmhmanagement.itg.cct-pubweb.com/nofapsaml', {
      method: 'GET',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json; charset=utf-8',
      },
    })
      .then(response => response.json())
      .then(data => {
        this.setState({ token: data });
      });
  }

  componentDidMount() {
    this.getToken();
  }

  render() {
  const { token } = this.state;
  return (
    <div className="app-container">
      <Navigation
        token={token}
      />
    </div>
  );
  }

Navigation.Js

export default class Navigation extends Component {



constructor(props) {
    super(props);

    this.state = {
      user: [],
      value: '',
    };
    this.getUserData = this.getUserData.bind(this);
  }

  componentDidMount() {
    setTimeout(() => {
      this.getUserData();
    }, 2000);
  }

  getUserData() {
    const { token } = this.props;
    let auth = token;
    fetch(url, {
      method: 'GET',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
        Authorization: `Bearer ${auth}`,
      },
    })
      .then(response => response.json())
      .then(result => {
        this.setState({ user: result });
      });
  }
render() {
const { user } = this.state;
return (
  <SideBarStyled>
      <UserInfo
        authorizedLots={user.authorizeLots}
      />
  </SideBarStyled>
);
}

Upvotes: 0

Views: 56

Answers (1)

Ravi Patel
Ravi Patel

Reputation: 169

You should never rely on timeout, because you never know the network latency.

Rather use like below :-

export default class Navigation extends Component {

constructor(props) {
    super(props);

    this.state = {
      user: [],
      value: '',
    };
    this.getUserData = this.getUserData.bind(this);
  }

  componentDidUpdate(prevProps) {
    if(prevProps.token !== this.props.token){
      this.getUserData();
    }
  }

  getUserData() {
    const { token } = this.props;
    let auth = token;
    fetch(url, {
      method: 'GET',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
        Authorization: `Bearer ${auth}`,
      },
    })
      .then(response => response.json())
      .then(result => {
        this.setState({ user: result });
      });
  }
render() {
const { user } = this.state;
return (
  <SideBarStyled>
      <UserInfo
        authorizedLots={user.authorizeLots}
      />
  </SideBarStyled>
);
}

Upvotes: 1

Related Questions