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

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

Войти через центр авторизации
Похожие вопросы