Reputation: 25
I want to create one function instead of several duplicate lines of code. I have this module. It`s works, but I want to optimize this code.
import React from 'react';
const form = (props) => {
//start
let arr = props.data.nodes.map((element) => element.vendor);
let unique = arr.filter(function(elem, index, self) {
return index === self.indexOf(elem);
});
let arr2 = props.data.nodes.map((element) => element.location);
let unique2 = arr2.filter(function(elem, index, self) {
return index === self.indexOf(elem);
});
let arr3 = props.data.nodes.map((element) => element.service);
let unique3 = arr3.filter(function(elem, index, self) {
return index === self.indexOf(elem);
});
let arr4 = props.data.nodes.map((element) => element.type);
let unique4 = arr4.filter(function(elem, index, self) {
return index === self.indexOf(elem);
});
//end
return(
<div className='wrapper'>
<form>
<label>
<p className="nameOfInput">Vendor</p>
<select onChange={props.filterOurData} >
<option>Choose vendor</option>
{unique.map((element) => <option key={element.toString()}>{element}</option>)}
</select>
</label>
<label>
<p className="nameOfInput">Location</p>
<select onChange={props.filterOurLocation} >
<option>Choose location</option>
{unique2.map((element) => <option key={element.toString()}>{element}</option>)}
</select>
</label>
<label>
<p className="nameOfInput">Service</p>
<select onChange={props.filterOurService} >
<option>Choose service</option>
{unique3.map((element) => <option key={element.toString()}>{element}</option>)}
</select>
</label>
<label>
<p className="nameOfInput">Device Type</p>
<select onChange={props.filterOurDeviceType} >
<option>Choose device type</option>
{unique4.map((element) => <option key={element.toString()}>{element}</option>)}
</select>
</label>
</form>
</div>
);
}
export default form;
I want to optimize code from the "start" to the "end", but I can't figure out how.
Link to the my small app: https://github.com/DrGreenNow/Relate-data
Upvotes: 1
Views: 50
Reputation: 104499
I will suggest you to create a separate component for Select and pass all the relevant info to that component. That component will be responsible of filtering the data and rendering the ui elements.
Data that you need to pass to Select Component will be:
data: to render the options
filterKey: to filter out the data
label: default label for the select field
change: function to handle change
Like this:
const form = (props) => {
return(
<div className='wrapper'>
<form>
<Select label="Vendor" onChange={props.filterOurData} filterKey="vendor" data={props.data.nodes} />
<Select label="Location" onChange={props.filterOurLocation} filterKey="location" data={props.data.nodes} />
<Select label="Service" onChange={props.filterOurService} filterKey="service" data={props.data.nodes} />
<Select label="Device Type" onChange={props.filterOurDeviceType} filterKey="type" data={props.data.nodes} />
</form>
</div>
);
}
const Select = (props) => {
let arr = props.data.map((element) => element[props.filterKey]);
let unique = arr.filter((elem, index, self) => index === self.indexOf(elem));
return (
<label>
<p className="nameOfInput">{props.label}</p>
<select onChange={props.onChange} >
<option>Choose {props.label}</option>
{unique.map((element) => <option key={element.toString()}>{element}</option>)}
</select>
</label>
)
}
Upvotes: 2
Reputation: 138
I've attempted to simplify it a bit
// setup dummy data
let props = {
data: {
nodes: []
}
};
for (let i = 0; i<10; i++) {
let node = {
vendor: "vendor"+ i,
location: "location" + i,
service: "service" + i,
type: "type" + i
}
props.data.nodes.push(node)
}
//start
let unique = []
let unique2 = []
let unique3 = []
let unique4 = []
props.data.nodes.map((element) => {
unique.push(element.vendor)
unique2.push(element.location)
unique3.push(element.service)
unique4.push(element.type)
})
//end
console.log(unique)
console.log(unique2)
console.log(unique3)
console.log(unique4)
console.log(props.data.nodes)
One map -> 4 arrays of data
Upvotes: 1