use-state-with-callback | Custom hook to include a callback function | Frontend Utils library
kandi X-RAY | use-state-with-callback Summary
Support
Quality
Security
License
Reuse
Currently covering the most popular Java, JavaScript and Python libraries. See a Sample Here
use-state-with-callback Key Features
use-state-with-callback Examples and Code Snippets
Trending Discussions on use-state-with-callback
Trending Discussions on use-state-with-callback
QUESTION
My app allows users to click on player cards in a Field section, and then for the selected player cards to appear in a Teams section. I have an array (called selectedPlayers) and initially, each element has a default player name and default player image. As the users select players, the elements in the array are replaced one-by-one by the name and image of the selected players.
The state of the array is set in a parent component and then the array is passed to a TeamsWrapper component as a prop. I then map through the array, returning a TeamsCard component for each element of the array. However, my TeamsCards are always one selection behind reality. In other words, after the first player is selected, the first card still shows the default info; after the second player is selected, the first card now reflects the first selection, but the second card still shows the default info. The code for the TeamsWrapper component is below:
import React from "react";
import "./style.css";
import TeamsCard from "../TeamsCard";
function TeamsWrapper(props) {
const { selectedPlayers } = props;
console.log('first console.log',selectedPlayers)
return (
{selectedPlayers.map((el, i) => {
console.log('second console.log',selectedPlayers)
console.log('third console.log',el)
return (
);
})}
);
}
export default TeamsWrapper;
I did have this working fine before when the parent was a class-based component. However, I changed it to a function component using hooks for other purposes. So, I thought the issue was related to setting state, but the console logs indicate something else (I think). After the first player is selected:
- the first console log shows a correctly updated array (i.e. the first element reflects the data for the selected player, not the placeholder data)
- the second console log reflects the same
- but the third print still shows the placeholder data for the first element
As mentioned above, as I continue to select players, this third print (and the TeamsCards) is always one selection behind.
EDIT:
Here is the code for the parent component (Picks), but I edited out the content that was not relevant to make it easier to follow.
import React, { useState } from "react";
import { useStateWithCallbackLazy } from "use-state-with-callback";
import TeamsWrapper from "../TeamsWrapper";
import FieldWrapper from "../FieldWrapper";
const Picks = () => {
const initialSelectedPlayers = [
{ playerName: "default name", image: "https://defaultimage" },
{ playerName: "default name", image: "https://defaultimage" },
{ playerName: "default name", image: "https://defaultimage" },
{ playerName: "default name", image: "https://defaultimage" },
{ playerName: "default name", image: "https://defaultimage" },
{ playerName: "default name", image: "https://defaultimage" },
];
const [count, setCount] = useStateWithCallbackLazy(0);
const [selectedPlayers, setSelectedPlayers] = useState(
initialSelectedPlayers
);
const handleFieldClick = (props) => {
// check to make sure player has not already been picked
const match = selectedPlayers.some(
(el) => el.playerName === props.playerName
);
if (match) {
return;
} else {
setCount(count + 1, (count) => {
updatePickPhase(props, count);
});
}
};
const updatePickPhase = (props, count) => {
if (count <= 15) {
updateTeams(props, count);
}
// elseif other stuff which doesn't apply to this issue
};
const updateTeams = (props, count) => {
const location = [0, 1, 2, 5, 4, 3];
const position = location[count - 1];
let item = { ...selectedPlayers[position] };
item.playerName = props.playerName;
item.image = props.image;
selectedPlayers[position] = item;
setSelectedPlayers(selectedPlayers);
};
return (
<>
);
};
export default Picks;
Thank you for your help!
ANSWER
Answered 2021-Mar-11 at 19:25When you update the array you are mutating state (updating existing variable instead of creating a new one), so React doesn't pick up the change and only re-render when count
changes, try
const updateTeams = (props, count) => {
const position = count - 1;
const newPlayers = [...selectedPlayers];
newPlayers[position] = {playerName:props.playerName, image:props.image}
setSelectedPlayers(newPlayers);
};
This way React will see it is a new array and re-render.
Community Discussions, Code Snippets contain sources that include Stack Exchange Network
Vulnerabilities
No vulnerabilities reported
Install use-state-with-callback
Support
Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from over 650 million Knowledge Items
Find more librariesExplore Kits - Develop, implement, customize Projects, Custom Functions and Applications with kandi kits
Save this library and start creating your kit
Share this Page