如何在React

时间:2018-06-03 19:25:04

标签: reactjs closures javascript-objects

我的假设是我尝试从闭包中访问状态。 这确实不起作用:

现有代码:

export class CityChoice extends React.Component{
constructor(props) {
    super(props);
    this.state={}
}

componentDidMount(){
  request
    .get('http://XXX.XXX.XX.XX:3000/get_courses')
    .set('Accept', 'application/json')
    .then((res) => {
        for (let key in res.body){
          console.log(res.body[key].city)
        }
      this.setState({courses: res.body})
        console.log("this.state.courses -> " + this.state.courses)
    })
    .catch(function(err) {
      console.log(err)
    });
}

render(){
  var that = this
  return (<div>
            <h2>Wähle Deine Stadt</h2>
            {
            that.state.courses.body.city.map((city, index) => (
              <p><Link to={{pathname: "/kurse", stadt: {city}}}><Button>{city}</Button></Link></p>
            ))}
            }
          </div>
        )
    }
}

预期结果

输出x按钮命名并链接到各个城市。

实际结果

TypeError:that.state.courses未定义

3 个答案:

答案 0 :(得分:3)

正在从服务器获取课程,因此响应将在处理请求后发出。但是在初始渲染函数中,没有名为courses的状态属性。所以你可以在构造函数中将它们设置为空。

constructor(props) {
 super(props);
 this.state={courses : {`what so ever is the data type`}}
}

在渲染时检查this.state.courses是否为空。

答案 1 :(得分:2)

您的组件尝试在异步提取完成之前呈现courses。因此,如果您无法将课程初始化为适当的空状态,请使用条件渲染,如@Tarik Sahni建议的那样。

{
    !this.state.courses
    ? ""
    : this.state.courses.body.city.map((city, index) => (
        <p><Link to={{pathname: "/kurse", stadt: {city}}}><Button>{city}</Button></Link></p>
    ))}
}

或者可能更简洁

{
    this.state.courses && this.state.courses.body.city.map((city, index) => (
        <p><Link to={{pathname: "/kurse", stadt: {city}}}><Button>{city}</Button></Link></p>
    ))}
}

您无需在渲染功能

中将this指定给that

答案 2 :(得分:1)

我对数据的形状有点困惑。循环遍历res.body,访问其值并在此代码中从每个值打印出一个带有关键城市的值:

    for (let key in res.body){
      console.log(res.body[key].city)
    }

然后,您将res.body分配给courses中的this.state密钥 这意味着状态有点像:

this.state = {
  courses: [
         { city: "New York"},
         { city: "San Francisco"},
         { city: "Jerusalem"},
         { city: "Ho Chi Minh"}
        ]
}

courses也可能是一个对象,但数组对我来说更有意义) 但是,当您访问该状态时,您编写以下表达式: that.state.courses.body.city.map。这意味着国家看起来更接近:

this.state = {
  courses: {
    body: {
      city: [
          "New York",
          "San Francisco",
          "Jerusalem",
          "Ho Chi Minh"
      ] 
    }
  }
}

现在因为这是JavaScript,可能是你在同一个对象中都有状态形状。但坦率地说,这似乎不太可能,如果是这样,那是不明智的。我的建议是简化状态形状,以便可以将未定义的错误隔离到您所缺失状态的特定部分。如果它必须是一个复杂的状态,请写出格式。