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 ponents here, but I would really like to make my renderMethod
works.
The logic is fine as per this jsbin:
,console
I can't figure out what I'm doing about react and JSX.
Any ideas?
Here is my code on codepen -
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=".1.0/react.min.js"></script>
<script src=".1.0/react-dom.min.js"></script>
<div id="root"></div>
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 ponents here, but I would really like to make my renderMethod
works.
The logic is fine as per this jsbin:
https://jsbin./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./ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
Share
Improve this question
edited Feb 1, 2017 at 9:55
Vinicius Santana
asked Feb 1, 2017 at 9:42
Vinicius SantanaVinicius Santana
4,1063 gold badges27 silver badges44 bronze badges
1
-
1
Firstly your console logs are causing a syntax error, you cant do something like this
return (a; b)
in JavaScript. Also your code pen is not transpiling the JSX to React functions, so the browser doesn't understand<div>
as JavaScript syntax. – James Hay Commented Feb 1, 2017 at 10:03
2 Answers
Reset to default 3From 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 ponent problems are as follows:
- In your constructor you are attempting to bind your
renderMethod
function to the context ofthis
. But to do that you need to usethis.renderMethod
otherwise it will look for a variable namedrenderMethod
which doesn't exist. - You are calling the bind on the result of the function, rather than the function itself. So you are executing the function immediately, returning a react object and trying to bind that. This is fixed by removing the parenthesis calling the function
this.renderMethod().bind(this)
beesthis.renderMethod.bind(this)
- In your render function, you are wrapping the
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). Soreturn ({this.renderMethod()})
beesreturn this.renderMethod();
- The return value of
renderMethod
is an Array, when it needs to be a single object. Commonly you can wrap this in a simplediv
to solve the issue. Remember that what you're creating is a SINGLE ponent, not a list of ponents, 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.
I see there are many things incorrect things in your code:
render
should return on one element, but in your code you are returning multiple elementsreturn
statement shouldn't haveconsole.log
. See it as
Incorrect:
return (a + b; console.log(a););
Correct:
console.log(a);
return (a + b);
map
should return single root element but you are returning multiple elements.elements.filter
should be in{}
as it is JS code not JSX.
Corrected Code:
class MyComponent extends React.Component{
constructor(props){
super(props);
this.renderMethod = 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 (
<div>
{groups.map(group => {
return(
<div>
<h1>{group.name}</h1>
{elements
.filter(element => group.status.includes(element.status))
.map(element => {
return(
<div>
<h1>{element.label}</h1>
<p>{element.status}</p>
</div>
)
})
}
</div>
)
})}
</div>
);
}
render() {
return (
<div>{ this.renderMethod() }</div>
)
}
}