如何将参数从组件传递到 redux 操作
How to pass argument from component to redux action
我试图将国家名称从 React 组件传递给 Redux 中的动作,但是当它到达动作创建者时,它变得未定义。我认为它与组件下方的 mapDispatchToProps() 部分有关,但我对 Redux 很陌生,所以我不完全确定。
它从 API 中获取国家列表,但是当我想将所选国家返回到 Actions.js 时,该国家变得未定义。
Component.js
import React, { useEffect, useState } from "react";
import { connect } from "react-redux";
import {
getCountryCasesAction,
getAllAvailableCountriesAction,
} from "../redux/Actions";
import { Form } from "semantic-ui-react";
function CasesByCountry({
countryOptions,
getAllAvailableCountries,
getCountryCases,
}) {
useEffect(() => {
getAllAvailableCountries();
}, [getAllAvailableCountries]);
const onDropdownOptionSelect = (e, result, country, countryData) => {
console.log(result.value);
getCountryCases(result.value);
};
return (
<div>
<Form.Dropdown
placeholder="Select Country"
fluid
selection
search
onChange={onDropdownOptionSelect}
options={
countryOptions &&
countryOptions.map((c) => {
return {
key: c.ISO2,
text: c.Country,
value: c.Country,
};
})
}
/>
</div>
);
}
const mapStateToProps = (state) => {
return {
countryOptions: state.data,
countryData: state.data,
};
};
const mapDispatchToProps = {
getAllAvailableCountries: getAllAvailableCountriesAction,
getCountryCases: getCountryCasesAction,
};
export default connect(mapStateToProps, mapDispatchToProps)(CasesByCountry);
Actions.js
import axios from "axios";
export const GET_WORLDWIDE_SUMMARY = "GET_WORLDWIDE_SUMMARY";
export const GET_COUNTRY_CASES = "GET_COUNTRY_CASES";
export const GET_ALL_AVAILABLE_COUNTRIES = "GET_ALL_COUNTRIES";
export const getWorldwideSummaryAction = () => async (dispatch, getState) => {
// const response = await axios
// .get
// // "https://cors-anywhere.herokuapp.com/" +
// // "process.env.REACT_APP_GET_WORLDWIDE_SUMMARY"
// ();
// console.log(response);
// return dispatch({
// type: GET_WORLDWIDE_SUMMARY,
// payload: response.data,
// });
};
export const getAllAvailableCountriesAction = () => async (
dispatch,
getState
) => {
const response = await axios.get("https://api.covid19api.com/countries");
console.log(response);
return dispatch({
type: GET_ALL_AVAILABLE_COUNTRIES,
payload: response.data,
});
};
export const getCountryCasesAction = () => async (
dispatch,
getState,
country
) => {
console.log("getCountryCasesAction");
const response = await axios.get(
`https://api.covid19api.com/dayone/country/${country}/status/confirmed`
);
console.log(response);
return dispatch({
type: GET_COUNTRY_CASES,
payload: response.data,
});
};
Reducer.js
import {
GET_WORLDWIDE_SUMMARY,
GET_ALL_AVAILABLE_COUNTRIES,
GET_COUNTRY_CASES,
} from "./Actions";
const initialState = {
data: "",
};
export const rootReducer = (state = initialState, action) => {
switch (action.type) {
case GET_WORLDWIDE_SUMMARY:
console.log(action.payload);
return {
...state,
data: action.payload,
};
case GET_ALL_AVAILABLE_COUNTRIES:
console.log(action.payload);
return {
...state,
data: action.payload,
};
case GET_COUNTRY_CASES:
console.log(action.payload);
return {
...state,
data: action.payload,
};
default:
return state;
}
};
你能试试这样调度你的动作吗?
//actions.js
export const getCountryCasesAction = (country) => async (
dispatch,
getState
) => {
const response = await axios.get(
`https://api.covid19api.com/dayone/country/${country}/status/confirmed`
);
console.log("CountryCaseAction", response);
return dispatch({
type: GET_COUNTRY_CASES,
payload: response.data,
});
};
//CasesByCountry.js
import React, { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import {
getCountryCasesAction,
getAllAvailableCountriesAction,
} from "../redux/Actions";
import { Form } from "semantic-ui-react";
function CasesByCountry() {
const dispatch = useDispatch();
const availableCountries = useSelector((state) => state.availableCountries);
const countryCases = useSelector((state) => state.countryCases);
useEffect(() => {
dispatch(getAllAvailableCountriesAction());
}, [dispatch]);
const optionForCountries =
availableCountries &&
availableCountries.map((country) => {
return {
key: country.ISO2,
text: country.Country,
value: country.Country,
};
});
console.log(countryCases);
return (
<div>
<Form.Dropdown
placeholder="Select Country"
fluid
selection
search
onChange={(result, e) => dispatch(getCountryCasesAction(e.value))}
options={optionForCountries}
/>
</div>
);
}
export default CasesByCountry;
//reducer.js
import {
GET_WORLDWIDE_SUMMARY,
GET_ALL_AVAILABLE_COUNTRIES,
GET_COUNTRY_CASES,
} from "./Actions";
const initialState = {
data: "",
availableCountries: "",
countryCases: "",
};
export const rootReducer = (state = initialState, action) => {
switch (action.type) {
case GET_WORLDWIDE_SUMMARY:
return {
...state,
data: action.payload,
};
case GET_ALL_AVAILABLE_COUNTRIES:
return {
...state,
availableCountries: action.payload,
};
case GET_COUNTRY_CASES:
return {
...state,
countryCases: action.payload,
};
default:
return state;
}
};
看来你在国家属性走错了路。
我在 CaseByCountry.js 文件中做了一些更改
...
return (
<div>
<Form.Dropdown
placeholder="Select Country"
fluid
selection
search
onChange={(result, e) => getCountryCases(e.value)}
//{(result) => dispatch(getCountryCases(result.value))}
options={
countryOptions &&
countryOptions.map((c) => {
return {
key: c.ISO2,
text: c.Country,
value: c.Country,
};
})
}
/>
</div>
);
}
...
const mapDispatchToProps = (dispatch) => ({
getAllAvailableCountries: () => dispatch(getAllAvailableCountriesAction),
getCountryCases: country => dispatch(getCountryCasesAction(country)),
});
此外,Actions.js 文件中的更改
export const getCountryCasesAction = (country) => async (
dispatch,
getState
) => {
console.log("getCountryCasesAction", country);
const response = await axios.get(
`https://api.covid19api.com/dayone/country/${country}/status/confirmed`
);
console.log(response);
return dispatch({
type: GET_COUNTRY_CASES,
payload: response.data,
});
};
国家不再是未定义的。但是出现了新的错误。既然不在问题范围内,我就干脆不提了。
请注意,我只复制了我更改的部分。
我试图将国家名称从 React 组件传递给 Redux 中的动作,但是当它到达动作创建者时,它变得未定义。我认为它与组件下方的 mapDispatchToProps() 部分有关,但我对 Redux 很陌生,所以我不完全确定。
它从 API 中获取国家列表,但是当我想将所选国家返回到 Actions.js 时,该国家变得未定义。
Component.js
import React, { useEffect, useState } from "react";
import { connect } from "react-redux";
import {
getCountryCasesAction,
getAllAvailableCountriesAction,
} from "../redux/Actions";
import { Form } from "semantic-ui-react";
function CasesByCountry({
countryOptions,
getAllAvailableCountries,
getCountryCases,
}) {
useEffect(() => {
getAllAvailableCountries();
}, [getAllAvailableCountries]);
const onDropdownOptionSelect = (e, result, country, countryData) => {
console.log(result.value);
getCountryCases(result.value);
};
return (
<div>
<Form.Dropdown
placeholder="Select Country"
fluid
selection
search
onChange={onDropdownOptionSelect}
options={
countryOptions &&
countryOptions.map((c) => {
return {
key: c.ISO2,
text: c.Country,
value: c.Country,
};
})
}
/>
</div>
);
}
const mapStateToProps = (state) => {
return {
countryOptions: state.data,
countryData: state.data,
};
};
const mapDispatchToProps = {
getAllAvailableCountries: getAllAvailableCountriesAction,
getCountryCases: getCountryCasesAction,
};
export default connect(mapStateToProps, mapDispatchToProps)(CasesByCountry);
Actions.js
import axios from "axios";
export const GET_WORLDWIDE_SUMMARY = "GET_WORLDWIDE_SUMMARY";
export const GET_COUNTRY_CASES = "GET_COUNTRY_CASES";
export const GET_ALL_AVAILABLE_COUNTRIES = "GET_ALL_COUNTRIES";
export const getWorldwideSummaryAction = () => async (dispatch, getState) => {
// const response = await axios
// .get
// // "https://cors-anywhere.herokuapp.com/" +
// // "process.env.REACT_APP_GET_WORLDWIDE_SUMMARY"
// ();
// console.log(response);
// return dispatch({
// type: GET_WORLDWIDE_SUMMARY,
// payload: response.data,
// });
};
export const getAllAvailableCountriesAction = () => async (
dispatch,
getState
) => {
const response = await axios.get("https://api.covid19api.com/countries");
console.log(response);
return dispatch({
type: GET_ALL_AVAILABLE_COUNTRIES,
payload: response.data,
});
};
export const getCountryCasesAction = () => async (
dispatch,
getState,
country
) => {
console.log("getCountryCasesAction");
const response = await axios.get(
`https://api.covid19api.com/dayone/country/${country}/status/confirmed`
);
console.log(response);
return dispatch({
type: GET_COUNTRY_CASES,
payload: response.data,
});
};
Reducer.js
import {
GET_WORLDWIDE_SUMMARY,
GET_ALL_AVAILABLE_COUNTRIES,
GET_COUNTRY_CASES,
} from "./Actions";
const initialState = {
data: "",
};
export const rootReducer = (state = initialState, action) => {
switch (action.type) {
case GET_WORLDWIDE_SUMMARY:
console.log(action.payload);
return {
...state,
data: action.payload,
};
case GET_ALL_AVAILABLE_COUNTRIES:
console.log(action.payload);
return {
...state,
data: action.payload,
};
case GET_COUNTRY_CASES:
console.log(action.payload);
return {
...state,
data: action.payload,
};
default:
return state;
}
};
你能试试这样调度你的动作吗?
//actions.js
export const getCountryCasesAction = (country) => async (
dispatch,
getState
) => {
const response = await axios.get(
`https://api.covid19api.com/dayone/country/${country}/status/confirmed`
);
console.log("CountryCaseAction", response);
return dispatch({
type: GET_COUNTRY_CASES,
payload: response.data,
});
};
//CasesByCountry.js
import React, { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import {
getCountryCasesAction,
getAllAvailableCountriesAction,
} from "../redux/Actions";
import { Form } from "semantic-ui-react";
function CasesByCountry() {
const dispatch = useDispatch();
const availableCountries = useSelector((state) => state.availableCountries);
const countryCases = useSelector((state) => state.countryCases);
useEffect(() => {
dispatch(getAllAvailableCountriesAction());
}, [dispatch]);
const optionForCountries =
availableCountries &&
availableCountries.map((country) => {
return {
key: country.ISO2,
text: country.Country,
value: country.Country,
};
});
console.log(countryCases);
return (
<div>
<Form.Dropdown
placeholder="Select Country"
fluid
selection
search
onChange={(result, e) => dispatch(getCountryCasesAction(e.value))}
options={optionForCountries}
/>
</div>
);
}
export default CasesByCountry;
//reducer.js
import {
GET_WORLDWIDE_SUMMARY,
GET_ALL_AVAILABLE_COUNTRIES,
GET_COUNTRY_CASES,
} from "./Actions";
const initialState = {
data: "",
availableCountries: "",
countryCases: "",
};
export const rootReducer = (state = initialState, action) => {
switch (action.type) {
case GET_WORLDWIDE_SUMMARY:
return {
...state,
data: action.payload,
};
case GET_ALL_AVAILABLE_COUNTRIES:
return {
...state,
availableCountries: action.payload,
};
case GET_COUNTRY_CASES:
return {
...state,
countryCases: action.payload,
};
default:
return state;
}
};
看来你在国家属性走错了路。
我在 CaseByCountry.js 文件中做了一些更改
...
return (
<div>
<Form.Dropdown
placeholder="Select Country"
fluid
selection
search
onChange={(result, e) => getCountryCases(e.value)}
//{(result) => dispatch(getCountryCases(result.value))}
options={
countryOptions &&
countryOptions.map((c) => {
return {
key: c.ISO2,
text: c.Country,
value: c.Country,
};
})
}
/>
</div>
);
}
...
const mapDispatchToProps = (dispatch) => ({
getAllAvailableCountries: () => dispatch(getAllAvailableCountriesAction),
getCountryCases: country => dispatch(getCountryCasesAction(country)),
});
此外,Actions.js 文件中的更改
export const getCountryCasesAction = (country) => async (
dispatch,
getState
) => {
console.log("getCountryCasesAction", country);
const response = await axios.get(
`https://api.covid19api.com/dayone/country/${country}/status/confirmed`
);
console.log(response);
return dispatch({
type: GET_COUNTRY_CASES,
payload: response.data,
});
};
国家不再是未定义的。但是出现了新的错误。既然不在问题范围内,我就干脆不提了。
请注意,我只复制了我更改的部分。