Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to update state while in a child component?

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

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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} />
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading