admin管理员组

文章数量:1420918

Whenever setState() is called, the ponent doesn't seem to rerender. As you can see by my ments, the state does in fact change and render seems to be called again, but if I don't add that if statement and simply add a paragraph tag that displays the data it will give me an error. I'm sure I'm missing something simple, but any help is appreciated.

import React from "react";
import axios from "axios";
import { constants } from "../constants/constants";
const { baseURL, apiKey, userName } = constants;

class User extends React.Component {
  constructor(props) {
  super(props);
  this.state = {
    user: []
  };
}
ponentDidMount() {
  let getUserInfo = axios.create({
    baseURL,
    url: `? 
    method=user.getinfo&user=${userName}&api_key=${apiKey}&format=json`
   });
  getUserInfo().then(response => {
  let data = response.data;
  console.log(data.user.playcount); //logs second, displays correct
  this.setState(state => ({
    user: data
  }));
});
}

render() {
  console.log(this.state); //logs first and third, doesn't work on first but does on third
  let toReturn;
  if (this.state.user.length > 0) {
    toReturn = <p>{this.state.user.user.playcount}</p>;
  } else {
    toReturn = <p>didn't work</p>;
  }
  return <div>{toReturn}</div>;
  }
}

export default User;

Whenever setState() is called, the ponent doesn't seem to rerender. As you can see by my ments, the state does in fact change and render seems to be called again, but if I don't add that if statement and simply add a paragraph tag that displays the data it will give me an error. I'm sure I'm missing something simple, but any help is appreciated.

import React from "react";
import axios from "axios";
import { constants } from "../constants/constants";
const { baseURL, apiKey, userName } = constants;

class User extends React.Component {
  constructor(props) {
  super(props);
  this.state = {
    user: []
  };
}
ponentDidMount() {
  let getUserInfo = axios.create({
    baseURL,
    url: `? 
    method=user.getinfo&user=${userName}&api_key=${apiKey}&format=json`
   });
  getUserInfo().then(response => {
  let data = response.data;
  console.log(data.user.playcount); //logs second, displays correct
  this.setState(state => ({
    user: data
  }));
});
}

render() {
  console.log(this.state); //logs first and third, doesn't work on first but does on third
  let toReturn;
  if (this.state.user.length > 0) {
    toReturn = <p>{this.state.user.user.playcount}</p>;
  } else {
    toReturn = <p>didn't work</p>;
  }
  return <div>{toReturn}</div>;
  }
}

export default User;
Share Improve this question asked Feb 8, 2019 at 20:00 thefc17thefc17 232 silver badges4 bronze badges 2
  • What is the error you're getting? Why are you sending state into your setState function? – jmargolisvt Commented Feb 8, 2019 at 20:24
  • @jmargolisvt when calling setState if you pass in a callback instead of an object, you are given the current state to use for updating, but his example doesn't do anything with it. – Isaac Vidrine Commented Feb 8, 2019 at 20:30
Add a ment  | 

2 Answers 2

Reset to default 2

React LifeCycle function sequence is Constructor and then it calls render method. In constructor method it initialises the state which is currently empty user array. Now it calls render() method as this.state.user is an empty array, referencing something out of it gives an error

this.state.user.user.playcount

this will generate an error if you dont have if condition. After the first render it will call ponentDidMount, now you fetch something update state. As setState occurred, render will be called again Now you have something in this.state.user then displaying will happen.

this.state.user.length > 0 is true

Look at this: https://reactjs/docs/react-ponent.html and https://reactjs/docs/conditional-rendering.html

You can right in single

tag using conditional render like this

<p>{this.state.user.length ? this.state.user.user.playcount : 'loading'}

Hope this helps.

I think your problem might have something to do with the changing shape of the user value. You initialise the value to an empty array, but then—after the fetch is done—you assume it's an object (by using user.user).

Maybe you could simplify the code a bit to look more like the one below?

/* imports */

class User extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      user: null // Make it explicit there's no value at the beginning.
    };
  }

  ponentDidMount() {
    let getUserInfo = axios.create(/* ... */);
    getUserInfo().then(response => {
      let data = response.data;
      this.setState({ // No need to for a setter function as you dno't rely on the previous state's value.
        user: data.user // Assign the user object as the new value.
      });
    });
  }

  render() {
    let toReturn;
    // Since it's now a `null`, you can use a simple existence check.
    if (this.state.user) {
      // User is now an object, so you can safely refer to its properties.
      toReturn = <p>{this.state.user.playcount}</p>;
    } else {
      toReturn = <p>No data yet.</p>;
    }
    return <div>{toReturn}</div>;
  }
}

export default User;

本文标签: javascriptComponent not rerendering on state changeStack Overflow