efremandre
@efremandre
Frontend Developer

Как добавить свойство к элементу массива в React Js?

Есть api, откуда беру массив с объектами. Возникла идея реализовать типа "лайки" или избранного. Чтобы кнопочку нажали, сохранилось и, или фильтр сделать или вывести лайкнутые на отдельную страничку.

Коротко: не получается сделать дизлайк, по нажатию на лайкнутую кнопку.

Набросал свой приложение тут:
https://codesandbox.io/s/beautiful-forest-kr23mt?f...

Получаю массив данных:

let [cards, setCards] = useState([])

	useEffect(() => {
		fetch('https://www.thecocktaildb.com/api/json/v1/1/filter.php?a=Alcoholic')
			.then(response => response.json())
			.then(data => setCards(data.drinks))
	}, [])


Создал колбэк от кнопки, которая добавляет к карточкам свойство isLike c значением true.

const like = (id) => {
		setCards(cards.map(c => (c.idDrink === id) ? { ...c, isLIke: true } : c))
	}


Делаю проверку в svg и крашу его в нужный цвет. Т.е. изменил данные и перекрасил ui в соответствии.

fill={el.isLIke ? 'red' : '#fff'}

Но проблема в том, что при повторном нажатии на кнопку, которая уже покрашена, ничего не происходит. Как я понял из-за того, что изначально в массиве нет свойства isLike.

Пытаюсь первоначально добавить к массиву это свойство, кнопка перестает работать. Словно перетирается действие колбека. Скорее всего код ниже ужасной кривой, я просто пока не знаю как сделать иначе. Ощущение что больше никто с этой проблемой не сталкивался, потому что гугление ни к чему особо не привело.

let [cards, setCards] = useState([])

	useEffect(() => {
		fetch('https://www.thecocktaildb.com/api/json/v1/1/filter.php?a=Alcoholic')
			.then(response => response.json())
			.then(data => setCards(data.drinks))
	}, [])

	cards.map(c => c.isLIke = false)

	const like = (id) => {
		setCards(cards.map(c => (c.idDrink === id) ? { ...c, isLIke: true } : c))
	}


Как я вижу решение своей задачи:
1. Поменять как-то изначальный массив, добавив ему свойство isLIke: false и работать с ним.
2. Переписать/ доболнить функцию колбека от кнопки.
  • Вопрос задан
  • 147 просмотров
Решения вопроса 1
efremandre
@efremandre Автор вопроса
Frontend Developer
Решил следующим образом
let [cards, setCards] = useState([])
	let [filter, setfilter] = useState(false)

	useEffect(() => {
		fetch('https://www.thecocktaildb.com/api/json/v1/1/filter.php?a=Alcoholic')
			.then(response => response.json())
			.then(data => setCards(data.drinks.map(c => !c.isLike ? { ...c, isLike: false } : c)))
	}, [])

	const like = (id) => {
		setCards(cards.map(c => (c.idDrink === id) ? { ...c, isLike: !c.isLike } : c))
	}


Т.е. добавил нужное мне свойство еще в then.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
szQocks
@szQocks
По хорошему с бэка уже должно прилетать этой свойство, а не на клиенте его создавать. - реализуй это.

На клиенте просто красишь свгшку в нужный цвет, в зависимости от значения isLike, когда пользователь нажимает лайк - отправляешь запрос в бд, где меняешь данные, если запрос прошёл успешно, изменяешь на клиенте в массиве поле. ( не важно true или false ) - суть одна.

проблема решена
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы