Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
4.0k 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 Answer

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...