Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
4.6k views
in Technique[技术] by (71.8m points)

reactjs - How to setState and useEffect correctly to read & display values from an object in React (hooks)?

The code below has a messages object. The code displays a list of each name within the messages object. By clicking on one of these names I would like to display the message associated with that name. I'm almost there, but I can't seem to work out what's wrong.

At the moment I'm getting a 'Objects are not valid as a React child' error on the second to last useEffect, where the code breaks, although the console.log does output an object with the id, name and message of the correct person. Can anyone help with what's causing the above error, and explain how I can reference the value within the object correctly.

import { useEffect, useState} from 'react'

function App() {

const messages = [
    {
        posterId: 0,
        posterName: "Matt",
        message: "This is Matt's test message"
    },
    {
        posterId: 1,
        posterName: "Gordon",
        message: "This is Gordon's test message"
    },
    {
        posterId: 2,
        posterName: "Stuart",
        message: "This is Stuart's test message"
    },

]

const [posterId, setPosterId] = useState('')
const [theMessageData, setTheMessageData] = useState([])
const [messageArray, setMessageArray] = useState([])
const [theActualMessage, setTheActualMessage] = useState('')


function updatePoster(id) {
    setPosterId(id)
}

useEffect(() => {
    console.log("The ID is: ",posterId);
    getIndividualMessage();
},[posterId])

function getIndividualMessage() {
    const messageVar = messages.filter(message => message.posterId === posterId);
    setTheMessageData(messageVar)
}

useEffect(() => {
    console.log("theMessageData array is: ",theMessageData[0]);
    setMessageArray(theMessageData[0])
},[theMessageData])

useEffect(() => {
     console.log("The actual message is: ",messageArray.message);
},[messageArray])

return (
    <>
        <div>
            <ul>
                { messages && messages.map(list => (
                    <li key={list.posterId}>
                        <button onClick={() => updatePoster(list.posterId)}>{list.posterName}</button>
                    </li>
                ))}
            </ul>
        </div>

        <div>
            <ul>
                <li>{theActualMessage}</li>
            </ul>
        </div>
    </>
);
}

export default App;

I did try putting the above in the snippets thing but I couldn't get that to work at all. Any help very much appreciated.

Cheers, Matt


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You are not setting your theActualMessage.

messageArray might not have been initialized. So use Optional Chaining as messageArray?.message

update your useEffect call as follows.

  useEffect(() => {
    console.log('The actual message is: ', messageArray?.message);
    setTheActualMessage(messageArray?.message) //This line was missing
  }, [messageArray]);

Working Snack


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...