我遇到的挑战是在局部状态下使用全局存储片(即“流派”)(即对象数组)来操纵复选框的选中/取消选中。当我尝试在初始状态下使用props.genres时,会发生问题。似乎在初始化本地状态时,我从props.genres中获取了一个空数组。
<div>
<label for="onoffswitch">
<span>Toggle dark mode on or off.</span>
</label>
<input
type="checkbox"
name="onoffswitch"
id="onoffswitch"
onclick="toggleDarkMode()"
/>
</div>
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
})
}
答案 0 :(得分:0)
您可以尝试通过props设置状态的初始值,但是这并不能反映最佳实践。考虑将您的数据初始为空数组并通过useEffect
操纵状态
// didn't understand if its array or bool
const [isChecked, setIsChecked] = useState([])
useEffect(()=>genres&& { setIsChecked(... perform action...)
} ,[genres])
答案 1 :(得分:0)
您的方法几乎是正确的。
当您获取数据时,我不确定状态应该如何。
我可以在mapStateToProps
中看到,尝试访问的是开头未定义的值。如果state.fetch
是undefined
,则无法访问genres
。
尝试1:
您可以使用lodash.get https://lodash.com/docs/#get解决此问题
它将解决undefined
问题。
尝试2: 您可以定义一个初始状态,其中您的值是使用模拟数据定义的。
const initialState = {fetch: {genres: []}}
并将其用作减速器