@AxelKroos
Junior Frontend

Почему state изменяется таким образом?

Добавляю новый объект в массив и он отрисовывается только после того, как я отправлю запрос ещё раз. Грубо говоря, всё добавляется как надо только на второе нажатие, то есть с опозданием.
Вот мой state:
import {CURRENT_CITY, ADD_CITY} from "./actions/actionTypes";

const initialState = {
    currentValue: '',
    currentCity: '',
    other: [{
        city: 'Gotham',
        country: 'DC',
        temp: 25,
        humidity: 10,
        wind: 3,
        feelsLike: 20
    }],
}

export default function currentWeather(state = initialState, action) {
    const weather = {}
    switch (action.type) {
        case CURRENT_CITY:
            return {
                ...state, currentValue: action.payload
            }
        case ADD_CITY:
            const addWeather = async () => {
                const api_key = '0a18303f01a73e215e930966eb1a77bc'
                const city = state.currentValue
                const api_url = await fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${api_key}&units=metric`)
                const data = await api_url.json()

                weather.city = data.name
                weather.country = data.sys.country
                weather.temp = data.main.temp
                weather.humidity = data.main.humidity
                weather.speed = data.wind.speed
                weather.feelsLike = data.main.feels_like
            }
            addWeather()
            return {
                ...state, currentValue: '',
                other: [...state.other, weather]
            }
        default:
            return state
    }
}


Компонент Form:
import React from 'react'
import {connect} from "react-redux";
import {changeValue, addCity} from "../../store/actions/actions";

class Form extends React.Component {
    render() {
        return (
            <div>
                <form onSubmit={(event => this.props.addCity(event.preventDefault()))}>
                    <input type="text" name='city' placeholder='Введите город' value={this.props.currentValue} onChange={(event => this.props.changeValue(event.target.value))}/>
                    <button>Добавить</button>
                </form>
            </div>
        )
    }
}


function mapStateToProps(state) {
    return {
        currentValue: state.currentWeather.currentValue
    }
}

function mapDispatchToProps(dispatch) {
    return {
        changeValue: (value) => dispatch(changeValue(value)),
        addCity: () => dispatch(addCity())
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(Form);


Компонент Weather:
import React from 'react'
import classes from './weather.module.css'
import {connect} from "react-redux";

class Weather extends React.Component {
    render() {
        const weather = this.props.other.map((elem) => {
            return (
                <div>
                    <p>Город: <span style={{color: 'white'}}>{elem.city}, {elem.country}</span></p>
                    <p>Температура: <span style={{color: 'palegreen'}}>{elem.temp}°</span></p>
                    <p>Ветер: {elem.wind} м/c</p>
                    <p>Влажность: {elem.humidity}%</p>
                    <p>Ощущается как: {elem.feelsLike}°</p>
                </div>
            )

        })
        return (
            <div className={classes.weather}>
                {weather}
            </div>
        )
    }
}

const mapStateToProps = (state) => {
    return {
        other: state.currentWeather.other
    }
}

function mapDispatchToProps(dispatch) {
    return null
}

export default connect(mapStateToProps, mapDispatchToProps)(Weather);

При отправке формы в компоненте Form я ожидаю увидеть в компоненте Weather новый добавленный город, но вместо этого я получаю пустую форму, где все данные - это ' '. Пустая строка. При повторной отправке формы я получаю предыдущую форму, которую заполнял. И так при каждом клике. Почему отрисовывается с такой "задержкой"?
  • Вопрос задан
  • 110 просмотров
Решения вопроса 1
Simkav
@Simkav
Редюсер должен быть чистой функцией, то есть без побочных эфектов, почитайте еще разок про редакс и советую почитать про вот эту волшебную штуку как раз для того что вам надо
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы