I have a component called Blocks that gets data from the backend and maps them all to a child component called Block. I want to be able to update the Block name from within the child but how would I get this change to occur in the parent?
Blocks.js
const Blocks = ({ updateBlocks }) => {
const [blocks, setBlocks] = useState([])
useEffect(() => {
const getBlocks = async () => {
const blocksFromServer = await fetchBlocks()
setBlocks(blocksFromServer)
};
getBlocks()
}, []);
const fetchBlocks = async () => {
const res = await fetch("/api/getblocks")
const data = await res.json()
return data
}
return (
<form onSubmit={updateBlocks}>
{blocks.map((block) => (
<Block key={block.id} block={block} />
))}
<input type="submit" value="update"></input>
</form>
)
}
export default Blocks
Block.js
import React from "react"
import { useState } from "react"
const Block = ({ block }) => {
const [topic, setTopic] = useState('')
return (
<div className="block">
<input type="text" name="topic" value={block.topic} onChange={}></input>
<h4>{block.start_time} - {block.end_time}</h4>
<hr class="dashed" />
</div>
)
}
export default Block
>Solution :
There are many ways to handle shared state, though for a minimal change in your code, you could pass the child Block components an update function to use:
const handleNameChange = useCallback((blockId, newName) => {
const updatedBlocks = blocks.map((block) => {
if (block.id === blockId) {
block.name = name;
}
return block;
});
setBlocks(updatedBlocks);
}, [blocks]);
// ...
{blocks.map((block) => (
<Block key={block.id} block={block} onNameChange={handleNameChange} />
))}
In Block:
const { block, onNameChange } = props;
const handleOnChange = useCallback((event) => {
onNameChange(block.id, event.target.value);
}, [block.id]);
<input type="text" name="topic" value={block.topic} onChange={handleOnChange} />