React + Firebase 使用钩子?
Posted
技术标签:
【中文标题】React + Firebase 使用钩子?【英文标题】:React + Firebase using hooks? 【发布时间】: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 函数做其他函数所做的事情,只需使用钩子。 【参考方案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 以获得一些想法。
【讨论】:
以上是关于React + Firebase 使用钩子?的主要内容,如果未能解决你的问题,请参考以下文章
React Hooks + Firebase Firestore onSnapshot - 正确使用带有反应钩子的 Firestore 监听器
Firebase auth 和 React Hook - 从钩子返回函数不起作用
React Redux Firebase 无法获取 firebase.storage