So after every POST request, only composerName and message field are correctly displayed (don't want sorter node to be displayed) and the timestamp is not. When I console.log the data, everything is there. No error or warnings. I can also see everything in their place after a hard refresh of the page.
Also, when I type something into input text area, onChange seems to trigger re-render of the component after each keystroke, and then I can see the timestamp being displayed and even updated. Maybe I'm using useEffect hooks in a wrong way? I assume this is the issue but I can't move any further from here.
Chatroom.js before return jsx:
// import statements
const Chatroom = ({ match }) => {
// ...
const [messages, setMessages] = useState([])
const [message, setMessage] = useState('')
// ...
useEffect(() => {
let messagesRef = db
.ref(`REFERENCE`)
.orderByChild('sorter')
.limitToFirst(numOfMessagesPerLoad)
setMessagesLoading(true)
messagesRef.on('value', snapshot => {
const messagesList = []
snapshot.forEach(data => {
messagesList.push(data.val())
})
setMessages(messagesList)
setMessagesLoading(false)
})
return () => messagesRef.off()
}, [])
// ...
const postMessageHandler = async e => {
e.preventDefault()
setPosting(true)
try {
const newMessage = {
composerName:
'Name ' + Math.floor(Math.random() * 100).toString(), // just to make each composerName unique
creationTime: Date.now(),
sorter: Date.now() * -1,
message,
}
const res = await axios.post(`ENDPOINT`, newMessage)
setMessages([res.data.data.message, ...messages])
setMessage('')
setPosting(false)
} catch (error) {
console.error(error.message)
}
}
Chatroom.js return jsx:
return (
<>
<section className="main-comments">
<div className="main-comments-top">
// ...
<div className="comment-form">
<Form className="comment-send-form" onSubmit={postMessageHandler}>
<input
type="text"
name="text"
value={message}
placeholder="Say something..."
className="comment-form-input"
onChange={e => setMessage(e.target.value)}
/>
<Button
className="msg-send-button"
type="submit"
disabled={message.length === 0}
>
{posting ? (
<ClipLoader size={20} color="#8585ff" />
) : (
<span>Post</span>
)}
</Button>
</Form>
</div>
</div>
// ...
<div id="comments" className="comments">
<div className="comments-area">
{messages.length === 0 && !messagesLoading ? (
<div style={{ textAlign: 'center' }}>
<p>This feed has no messages yet.</p>
</div>
) : (
messages
.sort((a, b) => {
return a.sorter - b.sorter
})
.map(msg => (
<div className="com-each-comment" key={msg.creationTime}>
<div className="user-and-comment">
<p className="username-display">
<span>{msg.composerName}</span>
</p>
<p className="com-text-comment">{msg.message}</p>
</div>
<div className="comment-footer">
<small className="comment-timestamp">
{timeSince(msg.creationTime)} // this is not being displayed until hard refresh
// timeSince() is just a custom function that I wrote to change timestamp format
</small>
</div>
</div>
))
)}
</div>
</div>
</section>
</>
)
}
export default Chatroom
Thank you
More Info: When tested through postman, things work and get displayed just as expected