i have a "carousel" displaying fruits,
also has a like button beside the carousel,
im loading carousel items with fruits (arr of objects) which is a response of a GET req,
i used "loader" from react-router for this GET req,
fruits here is a list of fruits a user has,
different users have different "isLiked" properties
const response = useLoaderData()
const fruits = response.data;
fruits looks like this,
[
{
id: 1,
name: 'apple',
isLiked: true,
},
{
id: 2,
name: 'orange',
isLiked: false
},
{
id: 3,
name: 'pineapple',
isLiked: true
},
];
this is my component,
const Fruits = () => {
const [fruitIndex, setFruitIndex] = useState(0);
const [currentFruit, setCurrentFruit] = useState(fruits[fruitIndex]);
const isThisFruitLiked = currentFruit.isLiked;
const handlePreviousFruit = () => {
if (fruitIndex === 0) {
let lastFruitIndex = fruits.length - 1;
setFruitIndex(lastFruitIndex);
setCurrentFruit(fruits[lastFruitIndex]);
} else {
setFruitIndex((prev: any) => prev - 1);
setCurrentFruit(fruits[fruitIndex - 1]);
}
};
const handleNextFruit = () => {
if (fruitIndex >= fruits.length - 1) {
setFruitIndex(0);
setCurrentFruit(fruits[0]);
} else {
setFruitIndex((prev: any) => prev + 1);
setCurrentFruit(fruits[fruitIndex + 1]);
}
};
const handleLike = async (id, isLiked) => {
try {
const reqBody = {
id,
isLiked,
};
if (isLiked) { // like a fruit
const response = await axios.post(`/api/v1/fruits`, reqBody);
const statusIsOk = response.status === 200;
if (statusIsOk) {
// change no to yes in "p tag"
}
} else { // un-like a fruit
const response = await axios.delete(`/api/v1/fruits?id=${id}`);
const statusIsOk = response.status === 200;
if (statusIsOk) {
// change yes to no in "p tag"
}
}
} catch (error) {
console.error(error);
}
};
return (
<>
<div>
<p>
{' '}
{`Do i like ${currentFruit.name}? ${
currentFruit.isLiked ? 'yes' : 'no'
}`}
</p>
<button
onClick={() => {
/* like or un-like a fruit */
if (isThisFruitLiked) {
handleLike(currentFruit.id, false);
} else {
handleLike(currentFruit.id, true);
}
}}
>
like button
</button>
</div>
<br />
<br />
<button onClick={handlePreviousFruit}>previous</button>
<button onClick={handleNextFruit}>next</button>
</>
);
};
i want my component to re-render everytime i like/un-like the fruit,
with my implementation, i need to restart the page for the component to update.
2
Answers
Well currently you are not setting the state in your handleLike function, and because of that your page is not rerendering.
For this to work, you need to have your fruits as state.
Now you can update the liked field of fruits and call setFruits(…fruits).
However, you just want to force update keeping the current set up, you can use a dummy state to force an update.
This works because each object is different.