【问题标题】:React + Firebase using hooks?React + Firebase 使用钩子?
【发布时间】:2019-10-06 01:44:24
【问题描述】:

我找到了一个很棒的教程,介绍如何将 React 与 Firebase 结合使用,非常简单地将文本字段的数据存储在数据库中,但我不知道如何将其转换为使用 Hooks。那里没有太多关于使用 Hooks + Firebase 的教程,因此我将不胜感激!

import React, {useState} from 'react'
import fire from './fire'
import './App.css'

const App = () => {
  let [messageList, setMessageList] = useState([])

  const handleSubmit = (e) => {
    e.preventDefault()
  }

  return(
    <section>
    <form onSubmit={handleSubmit}>
      <input type="text"></input>
      <button>Test</button>
    </form>
    <span>Messages: {messageList}</span>
    </section>
  )
}

class ThisWorksButNotWithHooks extends React.Component {
  constructor(props) {
    super(props);
    this.state = { messages: [] }; // <- set up react state
  }
  componentWillMount(){
    /* Create reference to messages in Firebase Database */
    let messagesRef = fire.database().ref('messages').orderByKey().limitToLast(100);
    messagesRef.on('child_added', snapshot => {
      /* Update React state when message is added at Firebase Database */
      let message = { text: snapshot.val(), id: snapshot.key };
      this.setState({ messages: [message].concat(this.state.messages) });
    })
  }
  addMessage(e){
    e.preventDefault(); // <- prevent form submit from reloading the page
    /* Send the message to Firebase */
    fire.database().ref('messages').push( this.inputEl.value );
    this.inputEl.value = ''; // <- clear the input
  }
  render() {
    return (
      <form onSubmit={this.addMessage.bind(this)}>
        <input type="text" ref={ el => this.inputEl = el }/>
        <input type="submit"/>
        <ul>
          { /* Render the list of messages */
            this.state.messages.map( message => <li key={message.id}>{message.text}</li> )
          }
        </ul>
      </form>
    );
  }
}

export default App;

我知道它可以与 Firebase 正常通信,因为 ThisWorksButNotWithHooks 可以正常工作,这要感谢 https://www.codementor.io/yurio/all-you-need-is-react-firebase-4v7g9p4kf。通过查看一个简单的简单示例并通过反复试验从那里开始工作,我学得最好,所以如果我知道如何使用 Hooks 做到这一点,我可以处理更复杂的用法。

谢谢!

【问题讨论】:

  • 到底是什么问题?哪个函数得到什么结果,你期望它做什么?
  • 有人将我的帖子编辑为与我的问题无关的标题。诡异的。我希望 App 函数做其他函数所做的事情,只需使用钩子。

标签: reactjs firebase firebase-realtime-database react-hooks


【解决方案1】:

这样的事情应该可以工作。我并没有真正关注您的 Firebase 逻辑或返回的 html,只是展示了如何使用 useEffect 和 useState 挂钩:

const App = () => {
  const [messageList, setMessageList] = useState([])
  const [inputEl, setInputEl] = React.useState(null)
  
  React.useEffect(() => {
    /* Create reference to messages in Firebase Database */
    let messagesRef = fire.database().ref('messages').orderByKey().limitToLast(100);

    // As you are using a listener, declare it so it can be returned
    const listener = messagesRef.on('child_added', snapshot => {

      // Below logic just adds to the current 'messages' state  
      const message = { text: snapshot.val(), id: snapshot.key };
      const updatedMessagesArray = [...messageList].push(message)
      setMessageList(updatedMessagesArray)
    })

    return () => listener() // <== the listener returns the unsubscribe function, which the hook will automatically run when the component unmounts.

  }, []) // <== run once onMount

  async function addMessage(e){
    e.preventDefault(); // <- prevent form submit from reloading the page
    /* Send the message to Firebase */
    await fire.database().ref('messages').push( inputEl.value );
    setInputEl(null)
  }
  
  const handleSubmit = (e) => {
    e.preventDefault()
  }

 return(
    <section>
    <form onSubmit={handleSubmit}>
      <input type="text"></input>
      <button>Test</button>
    </form>
    <span>Messages: {messageList}</span>
    </section>
  )
  
}

将一个空数组作为第二个参数传递给 useEffect 钩子将告诉它只在组件挂载时运行一次,返回监听器将让钩子在组件卸载时取消订阅监听器。

【讨论】:

    【解决方案2】:

    根据the Firebase Realtime API page,useEffect() 主体应该以

    结尾
    return () => messagesRef.off('value', listener)
    

    因为 on() 返回的是监听器,而不是非监听器。 Firestore 的 onDataSnapshot() 是返回 unlistener 的那个。

    【讨论】:

    • 非常感谢!!!不知道为什么没有人注意到这一点,但它对我有用:)
    【解决方案3】:

    react-firebase-hooks 库为 Hooks + Firebase 提供了方便的方法。您可以查看他们的useList implementation 以获得一些想法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-27
      • 1970-01-01
      • 2022-08-19
      • 2021-03-08
      • 2019-06-28
      • 2020-06-01
      • 2021-09-29
      • 2020-01-12
      相关资源
      最近更新 更多