I got React noob question.. The thing is that I have great number of fuctions that is almost indentical except that the method name and the properites is the differences between this two code blocks.
In my example, the first method is named xxx and the next yyy. The properties are named aaa and bbb.
To the question, how can I loop this in a smart way so I don't need a bunch of almost identical methods? I want to have only one method.
xxxx(blogItemNum: number) {
return (
this.state.dataLoadedLeadershipBlogDataItems ? (
this.state.leadershipBlogDataItems.length > blogItemNum ?
<aaaa item={this.state.leadershipBlogDataItems[blogItemNum]} index={blogItemNum} labels={this.props.labels} /> : ""
)
: ""
);
}
yyyy(blogItemNum: number) {
return (
this.state.dataLoadedLeadershipBlogDataItems ? (
this.state.leadershipBlogDataItems.length > blogItemNum ?
<bbbb item={this.state.leadershipBlogDataItems[blogItemNum]} index={blogItemNum} labels={this.props.labels} /> : ""
)
: ""
);
}
Ideally, don't do the index check in the method at all, pass item and index directly into the function:
xxxx(item, index: number) {
return (
<aaaa item={item} index={index} labels={this.props.labels} />
);
}
That is, just move the common code out of the method to another shared place.
Also, if you are looping correctly over this.state.leadershipBlogDataItems, you won't actually need this.state.leadershipBlogDataItems.length > blogItemNum checks.
Related
I have a problem about implementing conditional rending in return part of functional component.
I got this kind of error shown below.
Cannot convert undefined or null to object
While some links have more than one link, others have only one link.
How can I fix my issue?
Here is my code shown below.
{Object.keys(projectDialog?.links).length > 1 ? (
projectDialog?.links
.map((link, index) => (
{link.icon}
))
) : (
{projectDialog?.links.icon}
)
}
You need additional check for cases if projectDialog or projectDialog?.links are null or undefined, for better readability and prevent from nested ternary conditional rendering I would write in such way:
...
if (!projectDialog || !projectDialog?.links) return null;
//after above check you can be sure that below return will be with defined values
return (
{Object.keys(projectDialog?.links).length > 1 ? (
projectDialog?.links.map((link, index) => (
{link.icon}
))
) : (
{projectDialog?.links.icon}
)
}
)
Hi I'm trying to display variants in two separate categories Color and Size, to do this I need to get data from the api, I can access "attributes", but I would like to be able to access 0 and 1 and map them, I have no idea how to do this.
{variants.length > 1 ? (
variants.attributes.map(({ name, values }) => (
<ProductOptions
key={`key-${name}`}
name={name}
values={values}
selectedOptions={selectedOptions}
setOptions={setOptions}
/>
))
) : (
<Fragment />
)}
Thank you so much!
As i understand the output of Array with 6 elements where each of that 6 has attributes and attributes is yet another array and you want to loop through those attributes so you need 2 loops. One to loop through parent array and seconds inside the child.
variants.map((variant) => {
variant.attributes.map((attribute) => {
console.log('attribute: ', attribute);
console.log('attribute id: ',attribute.id);
});
});
p.s. you may use forEach https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach but it has little difference in this case.
Also it seems like you working with ReactJS and building some JSX to put into rendered jsx. I would argue to form the array upfront and in final jsx just insert the rows, so your final jsx will be more readable, especially in cases of double loops or any more complex jsx.
const attributes = [];
variants.map((variant) => {
variant.attributes.map((attribute) => {
console.log('attribute: ', attribute);
console.log('attribute id: ',attribute.id);
attributes.push(<div key={attribute.id}>{attribute.id}</div>)
});
});
// later
return (
<div>
{attributes}
</div>
)
I have an array name task which contain objects. Objects have 3 property id, name and subTask. subTask also an array which contains object which have 2 properties id and name.
Now my question is that how to return element in component return of react.js.
example I want to do like this =>
render(){
return(
this.state.task.map((e,i)=>{
//return some elements based on task element
return <some element 1/>
//Also I want to check if an property subTask
//of object of task array have some objects or not
//if yes then return some elements based on
//subTask array element
if(e.subTask.length!==0){
e.subTask.map((e2,i2)=>{
return <some element 2/>
})
}
})
)
}
In this code if I return <some element 1> then I cannot execute if statement because of return. ButI want to execute if statement also.
How can I achieve this ?
Can someone here help me with this ?
You could write the following instead:
render() {
return this.state.task.map((e, i) => {
//return some elements based on task element
return (
<>
<SomeElement />
{e.subTask.length &&
e.subTask.map((e2, i2) => <SomeElement />)}
</>
);
});
},
This will render the first element, based on the parent, and if there are sub-tasks it will load those beneath the parent element
If you want to render on some condition, you can use the ES6 syntax for conditional rendering based on condition from mapping your array. Example below
return (
tasks.map((task) => {
if (subTask.length != 0) {
subTask.map(subtask) => return <SomeElement />
}
}
)
I am using react-admin framework and I am trying to print data from my array.
My array is looking like this:
enter image description here
As you can see it currently has 3 indexes. Each of them stores different data. I want to print these data on to same page.
I am aware that I need to use some sort of cycle (for, foreach), but I really dont know how to implement it in shorthand.
This is my code, that I need to loop:
ID: {this.state.source[index].Id}<br></br>
AuditDate: {this.state.source[index].AuditDate}<br></br>
UserId: {this.state.source[index].UserId}<br></br>
Resource: {this.state.source[index].EntitySet}<br></br>
Entity1: {this.state.source[index].Entity1}<br></br>
Entity2: {this.state.source[index].Entity2}<br></br>
Operation: {this.state.source[index].Operation}<br></br>
EndPoint: {this.state.source[index].EndPoint}<br></br>
Changes: {this.state.source[index].Changes}<br></br>
Any ideas how to loop this?
Thank you in advance
You can make use of map to iterate over array,
{
this.state.source && this.state.source.length > 0 && this.state.source.map(source => {
return <>
<div>ID: {source.Id}</div>
<div>AuditDate: {source.AuditDate}</div>
<div>UserId: {source.UserId}</div>
<div>Resource: {source.EntitySet}</div>
<div>Entity1: {source.Entity1}</div>
<div>Entity2: {source.Entity2}</div>
<div>Operation: {source.Operation}</div>
<div>EndPoint: {source.EndPoint}</div>
<div>Changes: {source.Changes}</div>
</>
})
}
renderSources() {
const sources = source.map((eachSource) => {
return (
<div>
<span>`ID: ${eachSource.Id}`</span>
<span>`AuditDate: ${eachSource.AuditDate}`</span>
<span>`UserId: ${eachSource.UserId}`</span>
<span>`Resource: ${eachSource.EntitySet}`</span>
<span>`Entity1: ${eachSource.Entity1}`</span>
<span>`Entity2: ${eachSource.Entity2}`</span>
<span>`Operation: ${eachSource.Operation}`</span>
<span>`EndPoint: ${eachSource.EndPoint}`</span>
<span>`Changes: ${eachSource.Changes}`</span>
</div>
);
});
return sources;
}
render() {
return (<div>{this.renderSources()}</div>);
}
I've been learning React for the past few weeks and one thing that I don't like is that I have to use ternary operator for if else inside the render function.
Something like:
function render() {
return (
{x==="Let's go" ? <Go /> : <Hold on />}
)
}
Is there a way I can use a traditional if-else or switch for that matter with jsx syntax in React?
I utilize a few approaches to clean up the render method of more complex components.
1) Use a variable. Before you are actually in the JSX portion (the return) you can use the flexibility of raw JS to build variables. To take your example...
function render() {
let body;
if (x === "Let's go") {
body = <Go />
} else {
body = <Hold on />;
}
return (
<div>
{body}
</div>
);
}
Note that the top level needs to be wrapped, just put an extra div in there.
2) Use a function. This example is probably a little too simplistic but you'll get the idea..
renderBody() {
let body;
if (x === "Let's go") {
body = <Go />
} else {
body = <Hold on />;
}
return (
{body}
)
}
render() {
return (
<div>
{renderBody()}
</div>
)
}
3) Use an array (really a subset of #1) but oftentimes I find scenarios where sometimes I need to return 1 element but other times I need to return a variable number of elements. I will create an array at the top of the function and then push/unshift elements onto the array. Note that any time that you are building an array you must provide a key for each element so that React can update it properly.
let els = [
<div key="always">Always here</div>
];
if (foo) {
els.push(<div key="ifFoo">Conditionally Here</div>)
}
And then you just use the {els} variable in your main JSX.
4) Return null when you don't want anything to render
I prefer this syntax
function render() {
if (x==="Let's go") return <Go />;
return <Hold on />;
}