我发现了一个关于将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;
由于https://www.codementor.io/yurio/all-you-need-is-react-firebase-4v7g9p4kf,因此ThisWorksButNotWithHooks可以正常工作,我知道它可以与Firebase正常通信。通过查看一个简单的简单示例并通过反复试验从那里学习,可以使我学得最好,因此,如果我知道如何使用Hooks做到这一点,那么我可以解决更复杂的用法。
谢谢!
答案 0 :(得分:0)
类似的事情应该起作用。我并没有真正关注您的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>
)
}
将空数组作为第二个arg传递给useEffect挂钩将告诉它仅在组件安装时运行一次,返回侦听器将使挂钩在组件卸载时取消订阅侦听器。
答案 1 :(得分:0)
根据the Firebase Realtime API page,useEffect()主体应以
结尾return () => messagesRef.off('value', listener)
因为on()返回侦听器,而不是取消侦听器。 Firestore的onDataSnapshot()是返回取消侦听器的那个。
答案 2 :(得分:0)
react-firebase-hooks
库为Hooks + Firebase提供了便捷的方法。您可以看看他们的useList
implementation以获得一些想法。