I'm trying to render a list based on an array of objects grouped by status as per const elements on snippet bellow.
I'm aware that I could create smaller components here, but I would really like to make my renderMethod
works.
The logic is fine as per this jsbin:
https://jsbin.com/cejiziyupa/edit?js,console
I can't figure out what I'm doing about react and JSX.
Any ideas?
Here is my code on codepen - http://codepen.io/vinicius5581/pen/rjJRvM?editors=0011
Component:
class MyComponent extends React.Component{
constructor(props){
super(props)
renderMethod().bind(this);
}
renderMethod(){
const elements = [
{ "id": 1, "label": "element1", "status": "status1"},
{ "id": 2, "label": "element2","status": "status2"},
{"id": 3, "label": "element3", "status": "status6"},
{ "id": 4, "label": "element3", "status": "status10"}
]
const groups = [
{ "name": "group1", "status" : ["status1", "status2", "status3", "status4"] },
{ "name": "group2", "status" : ["status5", "status6", "status7", "status8"] },
{ "name": "group3", "status" : ["status9", "status10"] }
]
return (
groups.map((group) => {
return(
console.log(group.name);
<h1>{group.name}</h1>
elements.filter((element) => group.status.includes(element.status)).map((element) =>{
return(
console.log(element.id);
<div>
<h1>{element.label}</h1>
<p>{element.status}</p>
</div>
)
})
)
})
)
}
render(){
return(
{this.renderMethod()}
)
}
}
ReactDOM.render(<MyComponent />, document.getElementById('root'));
Html:
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
From the top. Your codepen is not transpiling JSX, so you end up with <div>
tags inside your javascript which is causing syntax errors. Additionally, your console.log
statements are causing syntax errors, you can't do return(x; y)
in Javascript.
Now the actual react component problems are as follows:
renderMethod
function to the context of this
. But to do that you need to use this.renderMethod
otherwise it will look for a variable named renderMethod
which doesn't exist.this.renderMethod().bind(this)
becomes this.renderMethod.bind(this)
renderMethod
call in JSX style braces, I'm not sure if this works, it may, but it's unecessary to have that or the standard parenthesis (and arguably, even a seperate function call). So return ({this.renderMethod()})
becomes return this.renderMethod();
renderMethod
is an Array, when it needs to be a single object. Commonly you can wrap this in a simple div
to solve the issue. Remember that what you're creating is a SINGLE component, not a list of components, there is never a reason to return an Array.Now because of the JSX problem stated at the beginning, I couldn't get your page to render, so I remade it in standard React calls. I've added key parameters to get rid of warnings.
class MyComponent extends React.Component{
constructor (props) {
super(props);
this.renderMethod.bind(this);
}
renderMethod () {
const elements = [
{ "id": 1, "label": "element1", "status": "status1" },
{ "id": 2, "label": "element2","status": "status2" },
{ "id": 3, "label": "element3", "status": "status6" },
{ "id": 4, "label": "element3", "status": "status10" }
];
const groups = [
{ "name": "group1", "status" : ["status1", "status2", "status3", "status4"] },
{ "name": "group2", "status" : ["status5", "status6", "status7", "status8"] },
{ "name": "group3", "status" : ["status9", "status10"] }
];
return React.createElement('div', {}, groups.map(
group => elements.filter(element => group.status.includes(element.status)).map((element, index) => (
React.createElement('div', { key: 'el_' + index }, [
React.createElement('h1', { key: 'el_h1_' + index }, [element.label]),
React.createElement('p', { key: 'el_p_' + index }, [element.status])
])
))
));
}
render () {
return this.renderMethod();
}
}
ReactDOM.render(React.createElement(MyComponent), document.getElementById('root'));
And this would be equivalent to something like this in JSX
return (
<div>
{groups.map(
group => elements.filter(element => group.status.includes(element.status)).map((element, index) => (
<div key={'el_' + index}>
<h1>{element.label}</h1>
<p>{element.status}</p>
</div>
))
)}
</div>
);
I'm also not going to go into all the Array iteration you're doing there, but suffice to say, you shouldn't be doing that much work inside a render call.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With