Refresh a Component from sibling Component in React

Viewed 42

I have 2 sibling components namely <AddTask/> and <TaskList/> which are children of <Home/> component. Currently, when I add a new task in my ToDo App, it will be added but I need to refresh the page in order for it to display the new task. How can I refresh the <TaskList/> component immediately after I click the Add button in <AddTask/> component?

Here is my <AddTask/> Component


const AddTask = () => {
    const [task, setTask] = useState("");
    const [isPending, setIsPending] = useState(false);

    const handleClick = (e)=> {
        e.preventDefault();
        setIsPending(true);
        const todo = {task};

        fetch('http://localhost:8000/tasks', {
            method: 'POST',
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify(todo)
        })
        .then(()=>{
            setIsPending(false);
        })

    };

    return ( 
    
        <form className="new-task" onSubmit={handleClick}>
            <input className="input" 
                type="text" 
                required
                value={task}
                onChange= { (e)=> setTask(e.target.value) } 
            />
            <button className="add-task">Add</button>
        </form>
        
    );
}
 
export default AddTask;

This is the <Home/> Component

import TaskList from "./TaskList";
import useFetch from "./useFetch";

const Home = () => {
    const { data: task, isPending, error} = useFetch('http://localhost:8000/tasks');

    return (
        <div className="home">
            <AddTask />
            { error && <div>Failed to fetch data.</div> }
            { isPending && <div>Loading...</div> }
            { task && <TaskList task={task} /> }
        </div>
    );
}
 
export default Home;
1 Answers

In Home component, you need a tasks state so you can update that state in AddTask component

Home

import TaskList from "./TaskList";
import useFetch from "./useFetch";
import { useState, useEffect } from 'react'

const Home = () => {
    const [tasks, setTasks] = useState(null);
    const { data: task, isPending, error} = useFetch('http://localhost:8000/tasks');
    useEffect(() => {
        if (task) setTasks(task)
    }, [task])

    return (
        <div className="home">
            <AddTask setTasks={setTasks} />
            { error && <div>Failed to fetch data.</div> }
            { isPending && <div>Loading...</div> }
            { tasks && <TaskList task={tasks} /> }
        </div>
    );
}
 
export default Home;

AddTask

const AddTask = ({ setTasks }) => {
    const [task, setTask] = useState("");
    const [isPending, setIsPending] = useState(false);

    const handleClick = (e)=> {
        e.preventDefault();
        setIsPending(true);
        const todo = {task};

        fetch('http://localhost:8000/tasks', {
            method: 'POST',
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify(todo)
        })
        .then(()=>{
            setIsPending(false);
            setTasks(prev => ([...prev, task]))
        })

    };

    return ( 
    
        <form className="new-task" onSubmit={handleClick}>
            <input className="input" 
                type="text" 
                required
                value={task}
                onChange= { (e)=> setTask(e.target.value) } 
            />
            <button className="add-task">Add</button>
        </form>
        
    );
}
 
export default AddTask;
Related