Search code examples
reactjsfirebasefirebase-realtime-databaseuse-effect

Trigger react useEffect


I'm fetching data from a firebase db it works when the component renders, but I can't make it to fetch again when there is a new entry in my db.

What I've tried

I've tried passing a state to the dependency array of useEffect and I changed that state every time my form was submitted (That's the time when there's a new entry in my db)

App

    function App() {
  const [showForm, setShowForm] = useState(true);
  const [tasks, setTasks] = useState([]);
  const [isSubmitted, setIsSubmitted] = useState(true);

  //Fetch tasks from server
  const fetchData = () => {
    fetch(
      "https://react-task-tracker-8e519-default-rtdb.firebaseio.com/tasks.json"
    )
      .then((response) => {
        return response.json();
      })
      .then((data) => {
        const tasks = [];
        //Convert the data to an array so i can map over it
        for (const key in data) {
          const task = {
            id: key,
            ...data[key],
          };

          tasks.push(task);
        }

        setTasks(tasks);
      });
  };
  useEffect(() => {
    fetchData();
  }, [isSubmitted]);

  //Show/Hide form
  const onAddHandler = () => {
    setShowForm(!showForm);
  };

  const formSubmitted = () => {
    setIsSubmitted(!isSubmitted);
    console.log(isSubmitted);
  };
  return (
    <Container>
      <Header click={onAddHandler} isShown={showForm}></Header>
      {showForm ? <Form fs={formSubmitted}></Form> : ""}
      <Tasks tasks={tasks}></Tasks>
    </Container>
  );
}

export default App; 

Form

    function Form(props) {
  const [task, setTask] = useState();
  const [dayTime, setDayTime] = useState();
  const [reminder, setReminder] = useState();

  //Posting Form data to firebase (DUMMY API)
  const postFormData = (fullTask) => {
    fetch(
      "https://react-task-tracker-8e519-default-rtdb.firebaseio.com/tasks.json",
      {
        method: "POST",
        body: JSON.stringify(fullTask),
        headers: {
          "Content-Type": "application/json",
        },
      }
    );
  };

  //Make an object of form data
  const onSubmit = (e) => {
    e.preventDefault();
    const fullTask = {
      task: task,
      dayTime: dayTime,
      reminder: reminder,
    };

    //Post func call
    postFormData(fullTask);

    props.fs();
    //Field clearing
    setTask("");
    setDayTime("");
    setReminder("");
  };

  return (
    <AddForm onSubmit={onSubmit}>
      <FormControl>
        <Label>Task</Label>
        <Input
          type="text"
          placeholder="Add Task"
          onChange={(e) => setTask(e.target.value)}
          value={task}
          required
        ></Input>
      </FormControl>

      <FormControl>
        <Label>Day & Time</Label>
        <Input
          type="text"
          placeholder="Add Task"
          onChange={(e) => setDayTime(e.target.value)}
          value={dayTime}
          required
        ></Input>
      </FormControl>

      <FromControlCheck>
        <CheckLabel>Set Reminder</CheckLabel>
        <CheckInput
          type="checkbox"
          onChange={(e) => setReminder(e.currentTarget.checked)}
          value={reminder}
        ></CheckInput>
      </FromControlCheck>

      <Submit type="submit" value="Save Task"></Submit>
    </AddForm>
  );
}

export default Form; 

Solution

  • I would pass fetchData as a props to <Form>. When submitted, I would call it.

    Form

    const onSubmit = async (e) => {
        e.preventDefault();
        const fullTask = {
            task: task,
            dayTime: dayTime,
            reminder: reminder,
        };
    
        //Post func call
        await postFormData(fullTask);
    
        await props.fetchData();
        //Field clearing
        setTask("");
        setDayTime("");
        setReminder("");
    };
    

    Then remove the isSubmitted state.