您好我从api获取数据并且我想获取数据并将其呈现给dom,但我是错误“Uncaught TypeError:无法在Topicselect.render中读取未定义的属性'map'”
这基本上就是我正在做的事情,虽然我已经抽象出与问题没有直接关系的任何东西,例如实际主题名称,导入等:
class Topics extends Component{
constructor(props){
super(props);
this.state = {
topics: []
}
}
componentWillMount(){
fetch('/api').then((res)=>r.json().then((data)=>{
// push topics into this.state.topics somehow
})
console.log(this.state.topics) //returns ['topic1','topic2','topic3'];
}
render(){
const list = this.state.topics.map((topic)=>{
return(<li>{topic}</li>);
})
return(
<ul>
{list}
</ul>
)
}
}
谁能告诉我如何解决这个问题?我在这里看到一个答案,说使用componentDidMount而不是componentWillMount但是这对我不起作用
答案 0 :(得分:1)
获取后您缺少结束括号)
,确实建议您使用componentDidMount()
代替componentWillMount()
从API获取数据。
在您收到API中的数据后,请不要忘记使用this.setState({ topics: data.howeverYourDataIsStructured });
以确保重新呈现该组件。
class Topics extends Component{
constructor(props){
super(props);
this.state = {
topics: []
}
}
componentDidMount() {
fetch('/api').then((res)=>r.json().then((data)=>{
this.setState({ topics: data.topics });
}));
console.log(this.state.topics) //returns [];
}
render() {
console.log(this.state.topics) //returns [] the first render, returns ['topic1','topic2','topic3'] on the second render;
return(
<ul>
{this.state.topics.map(topic => (
<li>{topic}</li>
))}
</ul>
)
}
}
答案 1 :(得分:1)
确保使用setState()
更新您的状态,否则render()
无法触发更新dom。另外,请确保您不会覆盖当前状态,而是将新主题添加到旧主题中。 (与此案无关,但仍然很重要)
一种方法是:
componentDidMount() {
var currentTopics = this.state.topics;
fetch('/api').then((res) => r.json().then((data) => {
currentTopics.push(data);
}));
this.setState({'topics': currentTopics});
}
但你也可以在循环中调用setState()
。 setState()
does not work synchronously因此,在实际执行更改然后触发render
之前,如果要进行其他更改,它将首先等待。
componentDidMount() {
fetch('/api').then((res) => r.json().then((data) => {
this.setState((state) => ({ topics: [...state.topics, data]}));
}));
}