Dario Mitsev
Dario Mitsev

Reputation: 19

Replace State Component with Functional Component using Hooks in React

How to replace this code from State Component with Functional component and React Hooks

state = {
    todos: [],
  };

 componentDidMount() {

        fire
          .firestore()
          .collection("todos")
          .onSnapshot((snapshot) => {
            snapshot.docChanges().forEach((change) => {
              if (change.type === "added") {
                let newTodo = change.doc.data();
                this.setState({
                  todos: [...this.state.todos, newTodo],
                });
              }
            });
          });
      }
    });

Upvotes: 0

Views: 1065

Answers (3)

Dana Woodman
Dana Woodman

Reputation: 4522

Try something like:

function MyComponent() {
  const [todos, setTodos] = React.useState([])

  React.useEffect(() => {
    fire
      .firestore()
      .collection("todos")
      .onSnapshot((snapshot) => {
        snapshot.docChanges().forEach((change) => {
          if (change.type === "added") {
            let newTodo = change.doc.data();
            setTodos([...todos, newTodo]);
          }
        });
      });
  }, [])

  return (
    <div>{/* ... */}</div>
 )
}

Obviously, you should read the docs about functional components and the difference between class components.

Upvotes: 2

CuteShaun
CuteShaun

Reputation: 139

const [todos, setTodos] = useState([])

 useEffect(() => {

        fire
          .firestore()
          .collection("todos")
          .onSnapshot((snapshot) => {
            snapshot.docChanges().forEach((change) => {
              if (change.type === "added") {
                let newTodo = change.doc.data();
                setTodos((prevTodos) => [...prevTodos, newTodo]);
              }
            });
          });
      }
    });

}, [])

If this approach would have problems with rerender, try to wrap inner code in useCallback hook:

     const makeTodos = useCallback(() => {
        fire
          .firestore()
          .collection("todos")
          .onSnapshot((snapshot) => {
            snapshot.docChanges().forEach((change) => {
              if (change.type === "added") {
                let newTodo = change.doc.data();
                setTodos((prevTodos) => [...prevTodos, newTodo]);
              }
            });
          });
      }
    });
  }, [])

Then call this function in useEffect:

useEffect(() => {
  makeTodos();
}, [])

usseEffect, useState, and useCallback you can import from react:

Import React, {useState, useEffect, useCallback}  from 'react'

Upvotes: 0

Mahdi N
Mahdi N

Reputation: 2178

const [todos, setTodos] = React.useState([]);

React.useEffect(() => {
           fire
          .firestore()
          .collection("todos")
          .onSnapshot((snapshot) => {
            snapshot.docChanges().forEach((change) => {
              if (change.type === "added") {
                let newTodo = change.doc.data();
                setTodos(prevTodos => ([...prevTodos, newTodo]));
              }
            });
          });
}, [])

Upvotes: -1

Related Questions