2017-07-27 40 views
1

您好我正在从api中提取数据,我想采取数据并将其呈现给dom,但我错误“Uncaught TypeError:无法读取属性'map'未定义在Topicselect.render”提取数据,然后将其渲染到dom React

这里基本上是我在做什么,虽然我已经抽象化了什么,是不是这个问题直接相关的,如实际主题名称,进口等:

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

您发布的错误似乎不符合您的代码。你有上课“Topicselect”吗? – Philipp

回答

0

你后取缺少一个右括号)而且它确实推荐使用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

确保您使用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]})); 
    })); 
}