我正在开发一个反应应用程序,并注意到一个奇怪的行为。 当我尝试使用过滤器时,它会导致错误:
react-dom.production.min.js:106 Uncaught TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))
at _ (iterableToArray.js:2:40)
at x (toConsumableArray.js:6:36)
at setFilters (gallerySlice.js:92:8)
at createReducer.ts:294:20
at produce (immerClass.ts:94:14)
at createReducer.ts:293:18
at Array.reduce (<anonymous>)
at c (createReducer.ts:260:25)
at reducer (createSlice.ts:372:14)
at redux.js:560:29
令人困惑的是,它只发生在构建和部署的版本中!
过滤设置由两个反应选择模块组成,通过 rtk 切片进行协调。 切片在这里:
setFilters: (state, action) => {
const { kategorije, tagovi } = action.payload;
console.log('kategorije:', kategorije);
console.log('tagovi:', tagovi);
state.selectedFilters = {
kategorije: Array.isArray(kategorije)
? kategorije.filter(Boolean)
: [],
tagovi: Array.isArray(tagovi) ? tagovi.filter(Boolean) : [],
};
},
...
// Filteri
export const selectFilteredPhotos = state => {
const { kategorije, tagovi } = state.gallery.selectedFilters || {};
const allPhotos = state.gallery.photos;
if (!kategorije && !tagovi) {
return allPhotos;
}
return allPhotos.filter(photo => {
const kategorijaMatches =
!kategorije ||
kategorije.length === 0 ||
kategorije.every(
filter =>
photo.kategorija && photo.kategorija.includes(filter)
);
const tagoviIncluded =
!tagovi ||
tagovi.length === 0 ||
tagovi.every(
filter => photo.tagovi && photo.tagovi.includes(filter)
);
return kategorijaMatches && tagoviIncluded;
});
};
过滤组件有:
import React, { useState, useEffect } from 'react';
import Select from 'react-select';
import { useDispatch, useSelector } from 'react-redux';
import { setFilters } from '../redux/rtk/gallerySlice';
function KategorijeSelekt() {
const dispatch = useDispatch();
const selectedFilters = useSelector(
state => state.gallery.selectedFilters
);
const [filterSelected, setFilterSelected] = useState([]);
useEffect(() => {
setFilterSelected(selectedFilters?.kategorije || []);
}, [selectedFilters]);
const handleKategorijeFilterChange = selectedFilters => {
const selectedFilterValues = selectedFilters.map(
filter => filter.label
);
dispatch(setFilters({ kategorije: selectedFilterValues }));
setFilterSelected(selectedFilterValues);
};
const customKategorijeOptions = [
{ value: 'gospodarski_objekti', label: 'gospodarski objekti' },
{ value: 'vazni_objekti', label: 'važni objekti' },
{ value: 'vjerski_objekti', label: 'vjerski objekti' },
{ value: 'arhitektura', label: 'arhitektura' },
{ value: 'ekologija', label: 'ekologija' },
{ value: 'tradicijska_gradnja', label: 'tradicijska gradnja' },
{ value: 'spomenici', label: 'spomenici' },
{ value: 'prirodni_resursi', label: 'prirodni resursi' },
{ value: 'stanovnistvo', label: 'stanovništvo' },
{ value: 'poljoprivreda', label: 'poljoprivreda' },
{ value: 'stocarstvo', label: 'stočarstvo' },
{ value: 'infrastruktura', label: 'infrastruktura' },
];
const cusTom = {
control: styles => ({
...styles,
backgroundColor: 'transparent',
border: 'none',
borderTop: '1px solid black',
borderRadius: '0',
cursor: 'pointer',
}),
option: (styles, { data, isDisabled, isFocused, isSelected }) => {
return { ...styles, color: 'black', cursor: 'pointer' };
},
placeholder: styles => ({
...styles,
color: '#18aa00',
marginTop: '-13px',
marginLeft: '-8px',
fontSize: '22px',
}),
dropdownIndicator: provided => ({ ...provided, display: 'none' }),
indicatorSeparator: provided => ({
...provided,
display: 'none',
}),
menu: styles => ({
...styles,
zIndex: '9999',
cursor: 'pointer',
width: '46vw',
height: 'auto',
}),
};
return (
<div>
<Select
id='kategorije-select'
styles={cusTom}
placeholder='unesi/odaberi'
isSearchable
isMulti
options={customKategorijeOptions}
value={
selectedFilters?.kategorije
? selectedFilters?.kategorije.map(option => ({
label: option,
value: option,
}))
: []
}
onChange={handleKategorijeFilterChange}
getOptionValue={option => option.value}
getOptionLabel={option => option.label}
/>{' '}
<label
htmlFor='kategorije-select'
style={{
fontSize: '22px',
color: '#7e7e77',
}}
>
kategorije
</label>
</div>
);
}
export default KategorijeSelekt;
另一个:
import React, { useState, useEffect } from 'react';
import Select from 'react-select';
import { useDispatch, useSelector } from 'react-redux';
import { setFilters } from '../redux/rtk/gallerySlice';
function TagoviSelekt({ tagoviOptions }) {
const dispatch = useDispatch();
const selectedFilters = useSelector(
state => state.gallery.selectedFilters
);
const [filterSelected, setFilterSelected] = useState([]);
useEffect(() => {
// Initialize the state with selected filters when the component mounts
const initialSelectedFilters = selectedFilters?.tagovi || [];
setFilterSelected(
initialSelectedFilters.map(option => ({
label: option,
value: option,
}))
);
}, [selectedFilters]);
const handleTagoviFilterChange = selectedFilters => {
const selectedFilterValues = selectedFilters.map(
filter => filter.value
);
dispatch(setFilters({ tagovi: selectedFilterValues }));
// Update the local state when filters change
setFilterSelected(
selectedFilters.map(option => ({
label: option.label,
value: option.value,
}))
);
};
const cusTom = {
control: styles => ({
...styles,
backgroundColor: 'transparent',
border: 'none',
borderTop: '1px solid black',
borderRadius: '0',
cursor: 'pointer',
}),
option: (styles, { data, isDisabled, isFocused, isSelected }) => {
console.log('selekt', data, isDisabled, isFocused, isSelected);
return { ...styles, color: 'black', cursor: 'pointer' };
},
placeholder: styles => ({
...styles,
color: '#18aa00',
marginTop: '-13px',
marginLeft: '-8px',
fontSize: '22px',
}),
dropdownIndicator: provided => ({ ...provided, display: 'none' }),
indicatorSeparator: provided => ({
...provided,
display: 'none',
}),
menu: styles => ({ ...styles, zIndex: '999', cursor: 'pointer' }),
};
return (
<div>
<Select
styles={cusTom}
placeholder='unesi/odaberi'
isSearchable
isMulti
options={tagoviOptions}
value={
selectedFilters?.tagovi
? selectedFilters?.tagovi.map(option => ({
label: option,
value: option,
}))
: []
}
onChange={handleTagoviFilterChange}
getOptionValue={option => option.value}
getOptionLabel={option => option.label}
/>
<label
htmlFor='keyword-select'
style={{ color: '#7e7e77', fontSize: '22px' }}
>
ključne riječi
</label>
</div>
);
}
export default TagoviSelekt;
可重现的示例是here。
显然这个问题是由托管延迟引起的 - cpanel 上的反应并不完全实时......