Redux useReducer 和 mapDispatchToProps 不工作
Redux useReducer and mapDispatchToProps not working
我正在构建一个使用 redux 进行状态管理的 React 应用程序。
在 SearchField 组件中,我使用 useReducer 来处理搜索字段输入(cityField 和 countryField)。
当我提交时,fetchData 函数运行并向 API.
发送请求
SearchField 组件代码:
import React, { useReducer } from "react";
import { connect } from 'react-redux';
import { SET_CITY_FIELD, SET_COUNTRY_FIELD } from '../../redux/search-field/search-field.types';
import { reducer, INITIAL_STATE } from "../../redux/search-field/search-field.reducer";
import { fetchData } from '../../redux/weather-api-data/data.actions';
import { SearchFieldContainer, SearchInput, OptionalField, FormComponent } from './search-field.styles';
const SearchField = () => {
const [state, dispatch] = useReducer(reducer, INITIAL_STATE);
const { cityField, countryField } = state;
const onFormSubmit = e => {
e.preventDefault()
cityField.length < 1 ?
alert('Please insert a city')
:
fetchData(cityField, countryField);
}
return (
<SearchFieldContainer>
<FormComponent onSubmit={onFormSubmit}>
<SearchInput type="search" placeholder="Search City" aria-label="Search"
onChange={event => dispatch({ type: SET_CITY_FIELD, payload: event.target.value })}
/>
</FormComponent>
<FormComponent className='country-form' onSubmit={onFormSubmit}>
<SearchInput className='country' type="search" placeholder="Country" aria-label="Search"
onChange={event => dispatch({ type: SET_COUNTRY_FIELD, payload: event.target.value })}
/>
<OptionalField>OPTIONAL</OptionalField>
</FormComponent>
</SearchFieldContainer>
)
}
const mapDispatchToProps = dispatch => ({
fetchData: (cityField, countryField) => dispatch(fetchData(cityField, countryField))
})
export default connect(null, mapDispatchToProps)(SearchField);
问题是调用OnFormSubmit函数时,fetchData函数没有发送任何请求,控制台也没有报错。 searchField 和 countryField 数据存储正确(或者至少如果我在控制台中显示它们,我会得到实际值)。 fetchData 函数之前位于 App 中并且可以正常工作。
我提前感谢任何给我答案并试图找到解决方案的人。
获取数据代码:
export const fetchData = (cityField, countryField) => {
return (dispatch) => {
dispatch(fetchCurrentDataRequest())
axios.get(`https://api.openweathermap.org/data/2.5/weather?q=${cityField},${countryField}&units=metric&appid=MY_API_KEY`)
.then(response => {
const currentData = response.data
dispatch(fetchCurrentDataSuccess(currentData));
const { lat, lon } = currentData.coord
dispatch(fetchDailyDataRequest())
axios.get(`https://api.openweathermap.org/data/2.5/onecall?lat=${lat}&lon=${lon}&units=metric&exclude=current,minutely,hourly,alerts&appid=MY_API_KEY`)
.then(response => {
const dailyData = response.data.daily
dispatch(fetchDailyDataSuccess(dailyData))
})
.catch(error => {
const errorMessage = error.message
dispatch(fetchCurrentDataFailure(errorMessage))
})
})
.catch(error => {
const errorMessage = error.message
alert('No results found')
dispatch(fetchCurrentDataFailure(errorMessage))
})
}
我解决了使用 useDispatch 钩子而不是 mapdispatchToProps,所以新代码是:
import React, { useReducer } from "react";
import { useDispatch } from 'react-redux';
import { fetchData } from '../../redux/weather-api-data/data.actions';
import { reducer, INITIAL_STATE } from '../../redux/search-field/search-field.reducer';
import { SET_CITY_FIELD, SET_COUNTRY_FIELD } from '../../redux/search-field/search-field.types';
import { SearchFieldContainer, SearchInput, OptionalField, FormComponent } from './search-field.styles';
const SearchField = () => {
const dispatchData = useDispatch();
const [state, dispatch] = useReducer(reducer, INITIAL_STATE);
const { cityField, countryField } = state;
const onFormSubmit = e => {
e.preventDefault()
cityField.length < 1 ?
alert('Please insert a city')
:
dispatchData(fetchData(cityField, countryField));
}
return (
<SearchFieldContainer>
<FormComponent onSubmit={onFormSubmit}>
<SearchInput type="search" placeholder="Search City" aria-label="Search"
onChange={event => dispatch({ type: SET_CITY_FIELD, payload: event.target.value })}
/>
</FormComponent>
<FormComponent className='country-form' onSubmit={onFormSubmit}>
<SearchInput className='country' type="search" placeholder="Country" aria-label="Search"
onChange={event => dispatch({ type: SET_COUNTRY_FIELD, payload: event.target.value })}
/>
<OptionalField>OPTIONAL</OptionalField>
</FormComponent>
</SearchFieldContainer>
)
}
export default SearchField;
我正在构建一个使用 redux 进行状态管理的 React 应用程序。 在 SearchField 组件中,我使用 useReducer 来处理搜索字段输入(cityField 和 countryField)。 当我提交时,fetchData 函数运行并向 API.
发送请求SearchField 组件代码:
import React, { useReducer } from "react";
import { connect } from 'react-redux';
import { SET_CITY_FIELD, SET_COUNTRY_FIELD } from '../../redux/search-field/search-field.types';
import { reducer, INITIAL_STATE } from "../../redux/search-field/search-field.reducer";
import { fetchData } from '../../redux/weather-api-data/data.actions';
import { SearchFieldContainer, SearchInput, OptionalField, FormComponent } from './search-field.styles';
const SearchField = () => {
const [state, dispatch] = useReducer(reducer, INITIAL_STATE);
const { cityField, countryField } = state;
const onFormSubmit = e => {
e.preventDefault()
cityField.length < 1 ?
alert('Please insert a city')
:
fetchData(cityField, countryField);
}
return (
<SearchFieldContainer>
<FormComponent onSubmit={onFormSubmit}>
<SearchInput type="search" placeholder="Search City" aria-label="Search"
onChange={event => dispatch({ type: SET_CITY_FIELD, payload: event.target.value })}
/>
</FormComponent>
<FormComponent className='country-form' onSubmit={onFormSubmit}>
<SearchInput className='country' type="search" placeholder="Country" aria-label="Search"
onChange={event => dispatch({ type: SET_COUNTRY_FIELD, payload: event.target.value })}
/>
<OptionalField>OPTIONAL</OptionalField>
</FormComponent>
</SearchFieldContainer>
)
}
const mapDispatchToProps = dispatch => ({
fetchData: (cityField, countryField) => dispatch(fetchData(cityField, countryField))
})
export default connect(null, mapDispatchToProps)(SearchField);
问题是调用OnFormSubmit函数时,fetchData函数没有发送任何请求,控制台也没有报错。 searchField 和 countryField 数据存储正确(或者至少如果我在控制台中显示它们,我会得到实际值)。 fetchData 函数之前位于 App 中并且可以正常工作。 我提前感谢任何给我答案并试图找到解决方案的人。
获取数据代码:
export const fetchData = (cityField, countryField) => {
return (dispatch) => {
dispatch(fetchCurrentDataRequest())
axios.get(`https://api.openweathermap.org/data/2.5/weather?q=${cityField},${countryField}&units=metric&appid=MY_API_KEY`)
.then(response => {
const currentData = response.data
dispatch(fetchCurrentDataSuccess(currentData));
const { lat, lon } = currentData.coord
dispatch(fetchDailyDataRequest())
axios.get(`https://api.openweathermap.org/data/2.5/onecall?lat=${lat}&lon=${lon}&units=metric&exclude=current,minutely,hourly,alerts&appid=MY_API_KEY`)
.then(response => {
const dailyData = response.data.daily
dispatch(fetchDailyDataSuccess(dailyData))
})
.catch(error => {
const errorMessage = error.message
dispatch(fetchCurrentDataFailure(errorMessage))
})
})
.catch(error => {
const errorMessage = error.message
alert('No results found')
dispatch(fetchCurrentDataFailure(errorMessage))
})
}
我解决了使用 useDispatch 钩子而不是 mapdispatchToProps,所以新代码是:
import React, { useReducer } from "react";
import { useDispatch } from 'react-redux';
import { fetchData } from '../../redux/weather-api-data/data.actions';
import { reducer, INITIAL_STATE } from '../../redux/search-field/search-field.reducer';
import { SET_CITY_FIELD, SET_COUNTRY_FIELD } from '../../redux/search-field/search-field.types';
import { SearchFieldContainer, SearchInput, OptionalField, FormComponent } from './search-field.styles';
const SearchField = () => {
const dispatchData = useDispatch();
const [state, dispatch] = useReducer(reducer, INITIAL_STATE);
const { cityField, countryField } = state;
const onFormSubmit = e => {
e.preventDefault()
cityField.length < 1 ?
alert('Please insert a city')
:
dispatchData(fetchData(cityField, countryField));
}
return (
<SearchFieldContainer>
<FormComponent onSubmit={onFormSubmit}>
<SearchInput type="search" placeholder="Search City" aria-label="Search"
onChange={event => dispatch({ type: SET_CITY_FIELD, payload: event.target.value })}
/>
</FormComponent>
<FormComponent className='country-form' onSubmit={onFormSubmit}>
<SearchInput className='country' type="search" placeholder="Country" aria-label="Search"
onChange={event => dispatch({ type: SET_COUNTRY_FIELD, payload: event.target.value })}
/>
<OptionalField>OPTIONAL</OptionalField>
</FormComponent>
</SearchFieldContainer>
)
}
export default SearchField;