Я написал приведенный ниже код, в котором город, в котором функция оповещения изначально работает нормально, если введено неправильное название города или название города не указано. Но после того, как здесь снова отображаются сведения о погоде, когда я нажимаю на кнопку «Отправить», он повторно отображает предыдущее состояние и новое и дает оба результата.

Код:

import React, { FC, useState, FormEvent } from "react";
import { useDispatch } from "react-redux";
import { Header, Input, Button } from "../style";
import {
  getWeather,
  setLoading
} from "../../store/actions/WeatherAction/weatherActions";
import { setAlert } from "../../store/actions/AlertAction/alertActions";

interface SearchProps {
  title: string;
}

const Search: FC<SearchProps> = ({ title }) => {
  const dispatch = useDispatch();

  const [city, setCity] = useState("");

  const changeHandler = (e: FormEvent<HTMLInputElement>) => {
    setCity(e.currentTarget.value);
  };

  const submitHandler = (e: FormEvent<HTMLFormElement>) => {
    e.preventDefault();

    dispatch(setLoading());
    dispatch(getWeather(city));
    setCity("");
  };

  return (
    <>
      <Header>
        {title}
        <form onSubmit={submitHandler}>
          <Input
            type="text"
            placeholder="Enter city name"
            value={city}
            onChange={changeHandler}
          />
          <br />
          <Button>Search</Button>
        </form>
      </Header>
    </>
  );
};

export default Search;

WeatherAction.ts

import { ThunkAction } from "redux-thunk";
import { RootState } from "../..";
import {
  WeatherAction,
  WeatherData,
  WeatherError,
  GET_WEATHER,
  SET_LOADING,
  SET_ERROR
} from "../../types";

export const getWeather = (
  city: string
): ThunkAction<void, RootState, null, WeatherAction> => {
  return async (dispatch) => {
    try {
      const res = await fetch(
        `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=3020950b62d2fb178d82816bad24dc76`
      );
      if (!res.ok) {
        const resData: WeatherError = await res.json();
        throw new Error(resData.message);
      }

      const resData: WeatherData = await res.json();

      dispatch({
        type: GET_WEATHER,
        payload: resData
      });
    } catch (err) {
      dispatch({
        type: SET_ERROR,
        payload: err.message
      });
    }
  };
};

export const setLoading = (): WeatherAction => {
  return {
    type: SET_LOADING
  };
};

export const setError = (): WeatherAction => {
  return {
    type: SET_ERROR,
    payload: ""
  };
};

WeatherReducer

import {
  WeatherState,
  WeatherAction,
  GET_WEATHER,
  SET_LOADING,
  SET_ERROR
} from "../../types";

const initialState: WeatherState = {
  data: null,
  loading: false,
  error: ""
};

export default (state = initialState, action: WeatherAction): WeatherState => {
  switch (action.type) {
    case GET_WEATHER:
      return {
        data: action.payload,
        loading: false,
        error: ""
      };
    case SET_LOADING:
      return {
        ...state,
        loading: true
      };
    case SET_ERROR:
      return {
        ...state,
        error: action.payload,
        loading: false
      };
    default:
      return state;
  }
};

enter image description here

1
Yajnaseni Panda 23 Янв 2021 в 14:36

1 ответ

Лучший ответ

Проблема в том, что ваш редуктор не очищает данные о погоде при обработке действия SET_ERROR. Если вы хотите очистить данные о погоде при получении сообщения об ошибке, вы должны вернуть data на null следующим образом:

case SET_ERROR:
      return {
        data: null,
        error: action.payload,
        loading: false
      };
0
BudgieInWA 26 Янв 2021 в 02:57