reactjs - 将全局 redux 存储与组件的本地状态相结合
问题描述
我遇到的挑战是使用全局存储切片,即“流派”,它是一个对象数组,在本地状态下操作复选框的选中/取消选中。当我尝试在初始状态下使用 props.genres 时会出现问题。当本地状态被初始化时,看起来我从 props.genres 得到一个空数组。
const Filters = (props) => {
const { genres, getSelected, loadGenres, getGenres, clearFilters } = props
const [isChecked, setIsChecked] = useState(() =>
genres.map(genre => (
{id: genre.id, value: genre.name, checked: false}
))
)
const optionsSortBy = [
{name: 'Popularity descending', value: 'popularity.desc'},
{name: 'Popularity ascending', value: 'popularity.asc'},
{name: 'Rating descending', value: 'vote_average.desc'},
{name: 'Rating ascending', value: 'vote_average.asc'},
]
const d = new Date()
let currentYear = d.getFullYear()
let optionsReleaseDate = R.range(1990, currentYear + 1).map(year => (
{name: year + '', value: year}
))
useEffect(() => {
const url = `${C.API_ENDPOINT}genre/movie/list`
loadGenres(url, C.OPTIONS)
}, [])
const handleCheckbox = (e) => {
let target = e.target
getGenres(target)
}
const handleSelect = (e) => {
let target = e.target
let action = isNaN(target.value) ? 'SORT_BY' : 'RELEASE_DATE'
getSelected(action, target)
}
const handleSubmitBtn = (e) => {
e.preventDefault()
clearFilters()
}
return (
<form className={classes.FiltersBox}>
<Submit submited={handleSubmitBtn} />
<Select name="Sort By:" options={optionsSortBy} changed={handleSelect} />
<Select name="Release date:" options={optionsReleaseDate} changed={handleSelect} />
<Genres genres={isChecked} changed={handleCheckbox} />
</form>
)
}
const mapStateToProps = (state) => {
return {
genres: state.fetch.genres,
}
}
const mapDispatchToProps = (dispatch) => {
return {
loadGenres: (url, options) => dispatch(A.getApiData(url, options)),
getGenres: (targetItem) => dispatch({
type: 'CHECK_GENRES',
payload: targetItem
}),
getSelected: (actionType, targetItem) => dispatch({
type: actionType,
payload: targetItem,
}),
clearFilters: () => dispatch({type: 'CLEAR_FILTERS'})
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Filters);
import * as R from 'ramda';
import fetchJSON from '../utils/api.js';
export const getApiData = (url, options) => async (dispatch) => {
const response = await fetchJSON(url, options)
const data = response.body
const dataHas = R.has(R.__, data)
let actionType = dataHas('genres') ? 'FETCH_GENRES' : 'FETCH_MOVIES'
dispatch({
type: actionType,
payload: data
})
}
export const fetchReducer = (state = initialState, action) => {
const { payload } = action
if (action.type === 'FETCH_GENRES') {
return {
...state,
isLoading: false,
genres: [...payload.genres]
}
}
if (action.type === 'FETCH_MOVIES') {
return {
...state,
isLoading: false,
movies: [...payload.results]
}
}
return state
}
解决方案
你的方法几乎是正确的。当您获取数据时,我不确定状态应该是什么样子。我可以看到mapStateToProps
正在尝试访问一开始未定义的值。如果state.fetch
是undefined
你无法访问genres
。
尝试一:你可以通过使用 lodash.get https://lodash.com/docs/#get来解决
它会赶上undefined
问题。
尝试 2:您可以定义一个初始状态,其中您的值是用模拟数据定义的。
const initialState = {fetch: {genres: []}}
并使用它作为你的减速器
推荐阅读
- python - 如何通过 Anaconda Spyder 使用 Google Cloud API?
- php - PHP如何检查记录是否存在(PDO)
- python - 如何使用 python 在地理地图上将边缘绘制为 3D 弧?
- android - 如何在我的应用程序中添加小提示或消息,我应该使用库吗?
- drupal - BrowserSync 和 Gulp 是否在本地主机上构建 drupal 时相互补充或竞争
- javascript - 你会如何在 Angular 6 中设计这个组件?
- opencv - 在 ARM Docker 容器中构建 OPENCV 时出现问题
- jquery - 基于国家代码的jquery简单重定向代码
- css - 加载 CSS 后渲染 SVG (React styled-components)
- python - 在 python 中打印图像中对象的边界大小时出现错误