ujuy
ujuy

Reputation: 65

How to take parameters from component to redux action creator

I'm using redux for the state management of my app, I'm still beginner using redux.

reducer.js

const initialState = {
  country: "Indonesia",
  countryName: [],
  countryConfirmed: 0,
  countryRecovered: 0,
  countryDeath: 0
};

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case GET_COUNTRY_NAME: {
      return {
        ...state,
        countryName: action.payload
      }
    }

    case GET_SELECTED_COUNTRY: {
      return {
        ...state,
        countryConfirmed: action.payload.countryConfirmed,
        countryRecovered: action.payload.countryRecovered,
        countryDeath: action.payload.countryDeath,
      }
    }

    case GET_PICK_COUNTRY: {
      return{
        ...state,
        country: action.payload
      }
    }

    default:
      return state;
  }
}

export default reducer;

action.js

export const getCountryName = (countryName) => {
  return {
    type: GET_COUNTRY_NAME,
    payload: countryName
  }
}

export const getCasesSelectedCountry = (confirmed, recovered, death) => {
  return {
    type: GET_SELECTED_COUNTRY,
    payload: {
      countryConfirmed: confirmed,
      countryRecovered: recovered,
      countryDeath: death,
    }
  }
}

export const getSelectedCountry = (country) => {
  return {
    type: GET_PICK_COUNTRY,
    payload: country
  }
}

Action creator file for fetching the api data

fetchDataAPI.js

export const getFetchCountryName = () => (dispatch) => {
  return (
    axios.get("https://covid19.mathdro.id/api/countries").then((result) => {
      let datas = result.data.countries;
      let name = [];
      datas.forEach((record) => {
        name.push(record.name);
      })

      dispatch({
        type: GET_COUNTRY_NAME,
        payload: name
      })
    })
      .catch((err) => {
        console.log(err);
      })
  )
}

export const getFetchCasesSelectedCountry = (country) => async (dispatch) => {
  await axios.get(`https://covid19.mathdro.id/api/countries/${country}`).then((result) => {
    let confirmed = result.data.confirmed.value;
    let recovered = result.data.recovered.value;
    let death = result.data.deaths.value;

    dispatch({
      type: GET_SELECTED_COUNTRY,
      payload: {
        countryConfirmed: confirmed,
        countryRecovered: recovered,
        countryDeath: death,
      }
    })
  })
    .catch((err) => {
      console.log("error message ", err);
    })

}

I have a form here where the value supposed to be in getFetchCasesSelectedCountry that being called by ${country}

import React from "react";
import "./style.css";
import { Form,Input } from "reactstrap";
import "../../Pages/style.css";
import { useDispatch, useSelector } from "react-redux";
import { getFetchCasesSelectedCountry, getFetchCountryName } from "../../redux/fetchDataAPI";

export default function DataCharts() {
  const countryState = useSelector(state => state)
  const dispatch = useDispatch();

  React.useEffect(() => {
    showAllCountry();
    pickCountry();

  }, [countryState.country]);

  const showAllCountry = (countryName) => {
    dispatch(getFetchCountryName(countryName))
  };

  const pickCountry = (confirmed, recovered, death) => {
    dispatch(getFetchCasesSelectedCountry(confirmed, recovered, death))
  };

  function handleChange() {
    pickCountry(countryState.country);
  }

  return (
    <>
      <div style={{ width: "30%", justifyContent: "center", margin: "2rem auto" }}>
        {/* THIS IS THE FORM */}
        <Form>
          <Input
            style={{ cursor: "pointer" }}
            type="select"
            name="selected"
            onChange={(e) => handleChange(e.target.value)}
            value={countryState.country}
          >
            {countryState.countryName.map((item, index) => (
              <option key={index} value={item}>
                {item}
              </option>
            ))}
          </Input>
        </Form>
      </div>
    </>
  );
}

How can I take the form value to my redux action creator file? Sorry if my question is hard to understand.

Upvotes: 2

Views: 227

Answers (1)

Drew Reese
Drew Reese

Reputation: 203466

pickCountry consumes 3 args: confirmed, recovered, and death. These are passed on to getFetchCasesSelectedCountry. You only pass countryState.country to pickCountry though. On top of that you never consume the new selected/onChange value from Input. I think this works out though since getFetchCasesSelectedCountry consumes a single arg, country.

Issue

The issue appears to simply be that the selected country value isn't consumed in the handleChange callback function and passed to pickCountry.

Solution

Update handleChange to consume the onChange event and forward the country value.

function handleChange(event) {
  const { value } = event.target; // <-- destructure value from event here
  pickCountry(value);
}

...

<Input
  style={{ cursor: "pointer" }}
  type="select"
  name="selected"
  onChange={handleChange} // <-- just attach handler
  value={countryState.country}
>
  {countryState.countryName.map((item, index) => (
    <option key={index} value={item}>
      {item}
    </option>
  ))}
</Input>

While code is being improved/fixed, may as well fix the other issue with pickCountry and getFetchCasesSelectedCountry.

const pickCountry = (country) => {
  dispatch(getFetchCasesSelectedCountry(country))
};

Upvotes: 1

Related Questions