在反应功能类中使用 useEffect 将数据写入 Firebase

时间:2021-04-03 22:06:47

标签: reactjs firebase firebase-realtime-database use-effect

代码持久地将数据存储在 Firebase 中,这是我每次会话后都想要的,但它很糟糕,因为由于异步,不应在相同的函数下调用 setOnes([...ones,1])writeToFirebase,但每次我尝试使用 useEffect(()=>writeToFirebase(),[setOnes]) 获得与 ComponentDidUpdate 类似的结果,它在启动开始时被触发并重置为 FB 数据库回 [1,1]。这是我的代码,代码和框链接:https://codesandbox.io/s/super-simple-react-firebase-functional-class-hook-set-up-eyo15?file=/src/App2.js:279-326

const App2 = () =>{
  
  const [ones, setOnes] = useState([1,1]);
  useEffect(() => {
    Firebase.initializeApp(config)
    getFromFirebase()
  }, []);

  // useEffect(()=>writeToFirebase(),[setOnes])

  const writeToFirebase = () => {
    Firebase.database()
      .ref("/")
      .set(ones);
    console.log("DATA SAVED");
  };

  const getFromFirebase = () => {
    let ref = Firebase.database().ref("/");
    ref.on("value", snapshot => {
      const state = snapshot.val();
      setOnes(state)
    })
  }

  const handleAdd =() => {
    setOnes([...ones,1])
    writeToFirebase()
  }
    
    const list = ones.map((e,i)=>( 
        <div
            key={e.id}
        > {e} </div>
    ))
  
    return ( 
    <div>
      {list}
      <button onClick={handleAdd}>Add</button>
    </div> 
    )
}

export default App2;

2 个答案:

答案 0 :(得分:0)

你应该写 useEffect(()=>writeToFirebase(),[ones]) 而不是 // useEffect(()=>writeToFirebase(),[setOnes])

useEffect(()=>writeToFirebase(),[ones]) 表示 writeToFirebase 将在每次更改时执行。 ones 是这里的状态变量,setOnes 是一个函数。

答案 1 :(得分:0)

不要在 useEffect 中使用 setones 作为依赖项,使用 ones。 完整代码如下

const App2 = () =>{
  
  const [ones, setOnes] = useState([1,1]);
  useEffect(() => {
    Firebase.initializeApp(config)
    getFromFirebase()
  }, []);

  useEffect(()=>writeToFirebase(),[ones])

  const writeToFirebase = () => {
    Firebase.database()
      .ref("/")
      .set(ones);
    console.log("DATA SAVED");
  };

  const getFromFirebase = () => {
    let ref = Firebase.database().ref("/");
    ref.on("value", snapshot => {
      const state = snapshot.val();
      setOnes(state)
    })
  }

  const handleAdd =() => {
    setOnes([...ones,1])
  }
    
    const list = ones.map((e,i)=>( 
        <div
            key={e.id}
        > {e} </div>
    ))
  
    return ( 
    <div>
      {list}
      <button onClick={handleAdd}>Add</button>
    </div> 
    )
}

export default App2;

或者,如果您只想在 writeToFirebase() 更改时而不是在初始渲染时调用 ones,您可以使用自定义钩子 useDidUpdateEffect。您可以在此问题的答案中找到代码 React hooks useEffect only on update?。在这种情况下,完整的代码将如下所示

const App2 = () =>{
  
  const [ones, setOnes] = useState([1,1]);
  const isInitialMount = useRef(true);
  useEffect(() => {
    Firebase.initializeApp(config)
    getFromFirebase()
  }, []);

  
  useEffect(() => {
  if (isInitialMount.current) {
       isInitialMount.current = false;
     } else {
     writeToFirebase();
    }
  }, [ones]);

  const writeToFirebase = () => {
    Firebase.database()
      .ref("/")
      .set(ones);
    console.log("DATA SAVED");
  };

  const getFromFirebase = () => {
    let ref = Firebase.database().ref("/");
    ref.on("value", snapshot => {
      const state = snapshot.val();
      setOnes(state)
    })
  }

  const handleAdd =() => {
    setOnes([...ones,1])
  }
    
    const list = ones.map((e,i)=>( 
        <div
            key={e.id}
        > {e} </div>
    ))
  
    return ( 
    <div>
      {list}
      <button onClick={handleAdd}>Add</button>
    </div> 
    )
}

export default App2