Reputation: 3665
I have a React component that takes an array as a parameter. From this array it generates a list. In the parent component, the array is a state variable and whenever that state variable is updated I want the changes to be reflected in the child component.
What's happening is the component is being rendered once but none of the changes are being shown.
App.js:
import heatData from "./config/heats.json";
export default function App() {
const [selectedHeat, setSelectedHeat] = useState(heatData.heats.find((x) => x.heatNumber === 1));
const [selectedHeatNumber, setSelectedHeatNumber] = useState(1);
const heats = heatData.heats;
const heatEvents = ["EventA", "EventB", "EventC", "EventD"];
useEffect(() => {
const _selectedHeat = heatData.heats.find((x) => x.heatNumber === selectedHeatNumber);
setSelectedHeat(_selectedHeat);
}, [selectedHeatNumber]);
return (
<div>
<div>
<ul>
{heats.map((heat, i) => (
<li onClick={() => setSelectedHeatNumber(heat.heatNumber)}>
Heat #{heat.heatNumber}
</li>
))}
</ul>
<div>
{heatEvents.map((event, i) => (
// This renders once but when selectedHeat changes it doesnt re-render
<EventCard athletes={selectedHeat.athletes} />
))}
</div>
</div>
</div>
);
}
heats.json that's being imported:
{
"heats": [
{
"heatNumber": 1,
"athletes": ["PersonA, PersonB, PersonC"]
},
{
"heatNumber": 2,
"athletes": ["PersonD, PersonE, PersonF"]
}
]
}
EventCard.js:
export default function EventCard({ athletes }) {
const [userPrediction, setUserPrediction] = useState([...athletes]);
// Add methods to manipulate userPrediction
return (
<table>
<tbody>
{userPrediction.map((athlete, i) => (
<tr key={i}>
<td>{athlete}</td>
<td>Up</td>
<td>Down</td>
</tr>
))}
</tbody>
</table>
);
}
Here's the process:
heats.json
heats
to produce a menu which, when clicked, sets the current heatThe problem is that clicking the button changes the heat but the athletes in EventCard do not update.
Upvotes: 0
Views: 123
Reputation: 996
You should add this useEffect
to your EventCard.js
component, because you are setting the state
with athletes only first time and the state is not updating when the props change, so you should keep track the change in props
and then update state
accordingly. CodeSandBox
useEffect(() => {
setUserPrediction([...athletes]);
}, [athletes]);
Or you can use athletes
props directly like:
{athletes.map((athlete, i) => (
<tr key={i}>
<td>{athlete}</td>
<td>Up</td>
<td>Down</td>
</tr>
))}
Upvotes: 1