简体   繁体   English

React.js设置对象数组状态的问题

[英]Reactjs setting state of array of object issues

I'm new to Reactjs and I'm learning to change state properties using setState method. 我是Reactjs的新手,正在学习使用setState方法更改状态属性。 I have few questions regarding changing state in reactjs. 关于在reactjs中更改状态,我有几个问题。

I'm building a weather web using open weather API for education purpose. 我正在使用开放天气API构建天气网络以用于教育目的。 I'm saving some properties inside the state so that I can pass them as props to other components. 我正在状态中保存一些属性,以便可以将它们作为道具传递给其他组件。 The state is as follows: 状态如下:

export default class App extends Component {
    state ={
       error: null,
       temperature: null,
       WeatherName: null,
       isLoaded: false,
       Weather5days: [{}]
}

I have some normal properties(eg temperature, isLoaded) and also array of object called Weather5days. 我有一些常规属性(例如,温度,isLoaded)以及称为Weather5days的对象数组。 Here I'm going to save weather data for each 5 days; 在这里,我将每5天保存一次天气数据; data for each day will go into each array, total length of 5. I know javascript allows to declare array and object with unknown length(is that how you declare it though?), so I have declared it as above. 每天的数据将进入每个数组,总长度为5。我知道javascript允许声明长度未知的数组和对象(这是您如何声明的?),所以如上所述。 Hence the data in Weather5days it's going to look something like this: 因此,Weather5days中的数据将如下所示:

state = {
...
Weather5days = [{date: "8.21", temperature: "20"},
                {date: "8.22", temperature: "25"},
                {date: "8.23", temperature: "24"},
                ...so on
               ]

Now I wish to add/alter the properties of each array of Weather5days, eg Weather5days[0].temperature = '25' etc... I get this data from weather API as json(also in array) and assign the parsed data to the created Weather5days array object. 现在,我想添加/更改Weather5days的每个数组的属性,例如Weather5days [0] .temperature ='25'等等...我从weather API获得此数据作为json(也在数组中)并将解析后的数据分配给创建的Weather5days数组对象。

I did some googling and found out that I cannot directly mutate state, so I've done the following after fetching: 我做了一些谷歌搜索,发现我不能直接改变状态,所以在获取后我做了以下工作:

.then(json =>{
  this.setState(prevState => {
    const newItems = [...prevState.Weather5days];
    for(var i = 0; i < json.Forecasts.length; i++){
      newItems[i].date = json.Forecasts[i].Date;  
    }
    return {Weather5days: newItems};
  }

I used for loop here to save the date of all the parsed data from API to each array of Weather5days object. 我在这里使用了循环,将来自API的所有已解析数据的日期保存到Weather5days对象的每个数组中。 However, this is the error I get: 但是,这是我得到的错误:

TypeError: undefined is not an object (evaluating 'newItems[i].date = json.Forecasts[i].Date') TypeError:未定义不是对象(评估'newItems [i] .date = json.Forecasts [i] .Date')

I'm not quite sure why. 我不太确定为什么。 Maybe I declared the Weather5days object wrong, or should they be declared with a length in the first place? 也许我宣布了Weather5days对象错误,还是应该首先声明它们的长度? Thank you very much! 非常感谢你!

UPDATE I've fiddled around with the code and in state I tried to declare Weather5days array as follows and it worked: 更新我弄弄了代码,并且在状态下我尝试声明Weather5days数组,如下所示,它可以正常工作:

state = {
error: null,
temperature: null,
WeatherName: null,
isLoaded: false,
Weather5days: [{date:null},{date:null},{date:null},{date:null},{date:null}]

}; };

so all I did was literally create 5 array objects in the first place. 所以我所做的只是从头开始创建5个数组对象。 I don't know why though. 我不知道为什么。 However this isn't really the solution as some circumstances I won't know the length of the array in the first place. 但是,这并不是真正的解决方案,因为在某些情况下,我首先不知道数组的长度。 Any ideas? 有任何想法吗?

Using: import update from 'immutability-helper'; 使用:从“不变性帮助器”导入更新;

this.setState(prevState => update(prevState, {
    Weather5days: { $set: json.Forecasts}
})

Your state was (before edit) initialized with Weather5days: [{}] , an array with one element. 您的状态(在编辑之前)已使用Weather5days: [{}]初始化,该数组包含一个元素。 Then you copy the array in newItems and you read indexes greater than 0 using newItems[i].date that are out of bound in your for loop. 然后,将数组复制到newItems中,并使用newItems[i].date循环中超出范围的newItems[i].date读取大于0的索引。 Using a for loop in your use case is unsafe, you should use the Array's map method in order to return your new items : json.Forecasts.map((forecast, index) => ({} /* return your newItem */)) 在用例中使用for循环是不安全的,应该使用Array的map方法来返回新项目: json.Forecasts.map((forecast, index) => ({} /* return your newItem */))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM