获取数据然后渲染到dom React

IT技术 javascript reactjs
2021-05-17 01:58:12

嗨,我正在从 api 获取数据,我想获取数据并将其渲染到 dom 但我是错误“未捕获的类型错误:无法读取 Topicselect.render 处未定义的属性‘地图’”

这基本上就是我正在做的事情,尽管我已经抽象出与问题不直接相关的任何内容,例如实际主题名称、导入等:

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 但这对我不起作用

2个回答

)在获取之后缺少一个右括号,确实建议使用它componentDidMount()而不是componentWillMount()从 API 获取数据。

另外不要忘记this.setState({ topics: data.howeverYourDataIsStructured });在从 API 接收数据后使用以确保重新渲染组件。

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>
    )
  }
}

确保你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()不同步工作,因此它会先等待是否有其他更改,然后才会实际执行更改,然后触发render

componentDidMount() {
    fetch('/api').then((res) => r.json().then((data) => {
        this.setState((state) => ({ topics: [...state.topics, data]}));
    }));
}