Что случилось, ТАК. Я пытаюсь запомнить компонент React, но сталкиваюсь с проблемами, связанными с определением области действия. У меня есть компонент с отслеживанием состояния, который отображает список всех покемонов, которых можно добавить или удалить из списка избранного.
В настоящее время, когда я добавляю или удаляю один элемент избранного, весь список отображается повторно (что я пытаясь предотвратить). Я добавил в каждый элемент списка покемонов метод, который добавляет / удаляет покемона из списка избранного. Это работает для добавления одного покемона в список избранного, однако, когда я пытаюсь добавить второго покемона в избранное, React не распознает, что я уже добавил покемона в список избранного и, следовательно, устанавливает состояние в новый список с только одним покемоном (вторым, на которого я нажал).
Я предполагаю, что это связано с тем, что когда каждый элемент списка отображается, мой метод переключения ограничен начальным состоянием списка избранного (пустой массив), поэтому вызов setState внутри этого компонента стирает родительское состояние и перезаписывает новое состояние, содержащее только одного покемона, вместо двух что я добавил.
Итак, мне интересно, есть ли обходной путь для этого?
Компонент списка:
const List = ({ pokemonList, getSinglePokemon }) => {
const [tabSelected, setTab] = useState('all');
const [favorites, setFavorites] = useState([])
const [searchParams, updateSearchParams] = useState(null)
const addOrRemoveFavorite = (pokemon) => {
const indexOfPokemon = favorites.indexOf(pokemon)
const updatedList = (indexOfPokemon !== -1) ?
[...favorites.slice(0,indexOfPokemon), ...favorites.slice(indexOfPokemon + 1)] :
[...favorites, pokemon]
setFavorites(updatedList)
}
const filteredPokemon = pokemonList.filter((p) => p.includes(searchParams))
//prob just define the values of tabDictionary inline instead of declaring them as variables above
const tabDictionary = { search: filteredPokemon, favorites, all: pokemonList}
const pokeList = tabDictionary[tabSelected].map((p) => (
<ListItem
isFavorite={Boolean(favorites.includes(p))}
key={p}
getSinglePokemon={getSinglePokemon}
name={p}
addOrRemoveFavorite={addOrRemoveFavorite}
/>
))
return (
<div id='list' className='interface'>
<ListHeader setTab={setTab} />
{(() => {
switch (tabSelected) {
case 'search':
return(
<div>
<input
type='text' placeholder='Search Pokemon...'
onChange={(e) => updateSearchParams(e.target.value)}
/>
<div id='pokeList'>
{pokeList}
</div>
</div>
)
case 'favorites':
return(
<div id='pokeList'>
{pokeList}
</div>
)
default:
return(
<div id='pokeList'>
{pokeList}
</div>
)
}})()}
</div>
)
}
export default List;
Компонент элемента списка:
const ListItem = ({name, getSinglePokemon, isFavorite, addOrRemoveFavorite}) => {
return (
<li
className='listItem'
onClick={() => getSinglePokemon(name)}
>
{name}
<button onClick={() => {
addOrRemoveFavorite(name)
}}>
{isFavorite ? 'Remove fav' : 'Make Fav'}
</button>
</li>
)
}
const areEqual = (prevProps, nextProps) => prevProps.isFavorite === nextProps.isFavorite
export default React.memo(ListItem, areEqual);