无论何时调用setState(),组件似乎都不会重新呈现。正如您从我的评论中看到的那样,状态实际上确实发生了变化,并且渲染似乎再次被调用,但是如果我不添加该if语句,而只是添加一个显示数据的段落标记,则会给我一个错误。我确定我缺少一些简单的东西,但是可以提供任何帮助。
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: []
};
}
componentDidMount() {
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;
答案 0 :(得分:2)
React LifeCycle函数序列为Constructor,然后调用render方法。 在构造方法中,它初始化当前为空用户数组的状态。 现在它调用render()方法,因为this.state.user是一个空数组,引用其中的内容会产生错误
this.state.user.user.playcount
如果您没有if条件,这将产生一个错误。 在第一个渲染之后,它将调用componentDidMount,现在您获取一些更新状态。发生setState时,将再次调用render。现在,您在this.state.user中有了一些东西,然后显示就会发生。
this.state.user.length > 0 is true
看看这个:https://reactjs.org/docs/react-component.html和https://reactjs.org/docs/conditional-rendering.html
您可以使用这样的条件渲染直接在单个
标签中
<p>{this.state.user.length ? this.state.user.user.playcount : 'loading'}
希望这会有所帮助。
答案 1 :(得分:0)
我认为您的问题可能与user
值的形状变化有关。您将值初始化为一个空数组,但是在提取完成之后,您假设它是一个对象(通过使用user.user
)。
也许您可以简化一下代码,使其看起来更像下面的代码?
/* imports */
class User extends React.Component {
constructor(props) {
super(props);
this.state = {
user: null // Make it explicit there's no value at the beginning.
};
}
componentDidMount() {
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;