Как установить значения для элементов массива внутри setState

#reactjs

#reactjs

Вопрос:

У меня есть массив, вызываемый nextDayWeather в состоянии, и я хочу установить значения для этих элементов массива внутри setState . Мне нужно передать его в вызов компонента WeekTempretureControl , как я упоминаю в следующем коде. пожалуйста, направьте меня. Спасибо.

 const API_KEY = "422edb157a5c2e7a35763933c19def46";

class App extends Component {
  state = {
    nextDayWeather: [
      {
        id: 1,
        nextDayDate: new Date(),
        nextDayTempreture: 23.4,
        nextDayWeatherLabel: "rain"
      },
      {
        id: 2,
        nextDayDate: new Date(),
        nextDayTempreture: 28.4,
        nextDayWeatherLabel: "clear sky"
      },
      {
        id: 3,
        nextDayDate: new Date(),
        nextDayTempreture: 25.4,
        nextDayWeatherLabel: "broken clouds"
      }
    ]
  };

  getWeather = async e => {
    e.preventDefault();
    const city = e.target.elements.city.value;
    const api_call = await fetch(
      `http://api.openweathermap.org/data/2.5/forecast?q=${city}amp;APPID=${API_KEY}amp;units=metric`
    );
    const data = await api_call.json();
    console.log(data);

    this.setState({
      //nextDayDate: new Date(),
      //nextDayTempreture: data.list[0].main.temp,
      //nextDayWeatherLabel: data.list[0].weather[0].description,
    });
  };

  render() {
    // let {currentLocation, currentDate, currentTempreture, currentWeatherLabel, currentWind, currentHumidity, currentPressure } = this.state.currentWeather;
    let { nextDayWeather } = this.state;

    return (
      <div id="bsec" className="b-color body-sec">
        <div className="main-wrapper">
          <WeekTempretureControl nextDayWeather={nextDayWeather} />
        </div>
      </div>
    );
  }
}

export default App;
  

Ответ №1:

  setState({...state, nextDayWeather: state.nextDayWeather.map( (day,index) => {
  if (index === THE_INDEX_YOU_ARE_LOOKING_TO_CHANGE) {
    return {
      id: index,
      nextDayDate: new Date(),
      nextDayTempreture: 5,
      nextDayWeatherLabel: "Rain"
    }
  }
  return {...day}

})})
  

Сначала распределите свое состояние, чтобы все, что вы не меняете, было перенесено.

Вы берете массив на следующий день и сопоставляете его, распространяя каждый объект, если он не соответствует вашему индексу, затем по нужному вам индексу вы можете изменить его на все, что захотите.

Ответ №2:

Поскольку состояние должно постоянно обновляться, сначала скопируйте состояние с помощью clonedeep() из Lodash или с помощью операторов распространения,

затем обновите клонированный объект,

затем установите состояние, используя обновленные данные

 getWeather = async e => {
e.preventDefault();
const city = e.target.elements.city.value;
const api_call = await fetch(
  `http://api.openweathermap.org/data/2.5/forecast?q=${city}amp;APPID=${API_KEY}amp;units=metric`
);
const data = await api_call.json();
console.log(data);
let updatedArray = clonedeep(this.state.nextDayWeather);
 updatedArray.forEach(item => {
   item.nextDayDate = new Date()
   item.nextDayTemp = data.list[0].main.temp
   item.nextDayWeatherLabel = data.list[0].weather[0].description
  })
 // so the piont is we use forEach/map/find/filter methods of array to update 
  all or some 
  // and if you want to update any one item inside the above array then any 
one of filter/map/... etc
  updatedArray.forEach(item => {
    if(item.id === 1){
      item.nextDayDate = new Date()
     item.nextDayTemp = data.list[0].main.temp
     item.nextDayWeatherLabel = data.list[0].weather[0].description
   }
  })
  // the above forEach loop will update only the item with id === 1, rest of 
  the 
  items will remain same

  this.setState({
    nextDayWeather:updatedArray
  });
};