I have a React project set up to fetch an Object from a Firebase database and render this to my page. However I do not know how to render the data properly.
The data I am fetching looks like this:
{
"projects": {
"0": {
"title": "test",
"function": "test2"
},
"1": {
"title": "test3",
"function": "test4"
}
}
}
In the Chrome React Debugger I see this:
<div>
<Message key="0" data={function: "test2", title: "test", key: "0"}>...</Message>
<Message key="1" data={function: "test4", title: "test3", key: "1"}>...</Message>
</div>
But in the elements view I am simply seeing two empty divs:
<div>
<div></div> == $0
<div></div>
</div>
Currently I am passing <Message key={index} data={message} />
to a Message component containing {this.props.message}
EDIT: Changed this to {this.props.data} since no message prop was passed to Message component
Refactoring the code to: <div> key={index} data={message} </div>
however returns the error
Objects are not valid as a React child (found: object with keys {function, title, key}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of ProjectList.
Seeing as the project items have keys I do not believe CreateFragment is the correct solution. Also Firebase favors passing objects with keys over arrays so the solutions I am given does not seem to work in this situation. But how can I then control how the objects are rendered on the page?
My complete ProjectList component looks like this:
import React from 'react';
import firebase from 'firebase';
import _ from 'lodash';
import Message from './Message'
class ProjectList extends React.Component {
constructor(props){
super(props);
this.state = {
messages: {}
};
this.firebaseRef = firebase.database().ref('projects');
this.firebaseRef.on("child_added", (msg)=> {
if(this.state.messages[msg.key]){
return;
}
let msgVal = msg.val();
msgVal.key = msg.key;
this.state.messages[msgVal.key] = msgVal;
this.setState({messages: this.state.messages});
});
}
render(){
var messageNodes = _.values(this.state.messages).map((message, index)=> {
return (
<Message key={index} data={message} />
);
});
return (
<div>
{messageNodes}
</div>
);
}
}
export default ProjectList;
Thanks!
Edit: changed the Message component render to {this.props.data}
as Message component receives no message prop.
Regarding the error `Objects are not valid as a React child (found: object with keys {function, title, key}). I changed my prop from an object to an array. Finally I changed my message component to this.props.data since no message prop was passed as the other posters have noted.
The array fix:
Thank you so much for the help!
You are passing the prop to the message component by name
data
and rendering it usingthis.props.message
which is wrong.Use
this.props.data
.Change your
Message
render method to: