Reputation: 15
I am wondering how to make new blank array with objects in the state and how to add element in it with setState.
I want the array so:
newhosts: [
{
activityState : "",
platform: "",
pushDate: "",
name: "",
ip: "",
software: [{
vulnerability: {
link: "",
desc: "",
cvss: "",
cve: ""
},
vulnerable: '',
cpe: "",
version: "",
vendor: "",
name: ""
}]
}
]
Is it okay , so to declare the array in the state? How can I add later description oder items(for example description of the host and then description of all software elements on it). And how can I add for example two softwares to the same host?
const namearray= this.state.filteredhosts.map(host=> {
return (
host.software.map((sub, subindex) => {
if(selectedOption==="name" || selectedOption==="vendor") {
if(sub[selectedOption]=== writtenOption){
newState.push(host.meta.name)
newState.push(host.meta.ip)
newState.push(sub.name)
newState.push(sub.vendor)
}
}
else {
if(sub.vulnerable===true){
newState.push(sub.vulnerability[selectedOption])}
newState.push(host.meta.name)
newState.push(host.meta.ip)
}
})
)
})
Here I must replace this "newState.push" with your function, which save the data to the state.
Upvotes: 0
Views: 242
Reputation: 15708
Having an array as a state-value is completely valid. Consider the sandbox I made for you: https://codesandbox.io/s/deeply-nested-inputs-mf70m
Your question gave me some inspiration and writing this out actually taught me a lot about handling nested inputs and how to update them.
This code will show you how to:
host
object and the corresponding inputs for
the user to fill.activityState
, platform
,
etc.software
object inside a host, including the inner
vulnerability
object and outer-fields such as vulnerable
, cpe
, etc.software
object to a host. And then updating
those software objects.Fill out the form with any combination of hosts
and software
, when you're finished hit the Click to Log Hosts
button to print the finalized state
.
import React from "react";
class App extends React.Component {
state = {
newhosts: [
{
activityState: "",
platform: "",
pushDate: "",
name: "",
ip: "",
software: [
{
vulnerability: {
link: "",
desc: "",
cvss: "",
cve: ""
},
vulnerable: "",
cpe: "",
version: "",
vendor: "",
name: ""
}
]
}
]
};
handleOnChange = (event, hostindex, layer, softwareIndex) => {
const { newhosts } = this.state;
const copiedHosts = [...newhosts];
const updatedHosts = copiedHosts.map((host, index) => {
//find mathcing index to update that item
if (hostindex === index) {
//determine what layer of data we need to update
if (layer === 1) {
//we need to update activityState, platform etc...
return {
...host,
[event.target.name]: event.target.value
};
} else if (layer === 2) {
//now we need to find the matching software item to update
let updatedSoftware = copiedHosts[hostindex].software.map(
(software, sIndex) => {
if (softwareIndex === sIndex) {
return {
...software,
[event.target.name]: event.target.value
};
} else {
return {
...software
};
}
}
);
return {
...host,
software: updatedSoftware
};
} else if (layer === 3) {
//now we need to find the matching software item to update
let updatedSoftware = copiedHosts[hostindex].software.map(
(software, sIndex) => {
if (softwareIndex === sIndex) {
return {
...software,
vulnerability: {
...software.vulnerability,
[event.target.name]: event.target.value
}
};
} else {
return {
...software
};
}
}
);
return {
...host,
software: updatedSoftware
};
}
} else {
//return all other hosts
return host;
}
});
this.setState({
newhosts: updatedHosts
});
};
createNewHostsForm = () => {
const { newhosts } = this.state;
return newhosts.map((host, hostIndex) => {
return (
<div>
<h4>{`Host ${hostIndex + 1}`}</h4>
{Object.entries(host).map(([key, value], lvl1Index) => {
if (Array.isArray(value)) {
const secondLayerInputs = [...value];
return (
<div>
<strong>software:</strong>
{secondLayerInputs.map((input, softwareIndex) => {
return Object.entries(input).map(([lvl2Key, lvl2Value]) => {
if (typeof lvl2Value === "string") {
return (
<div>
<label>{lvl2Key}</label>{" "}
<input
value={lvl2Value}
name={lvl2Key}
onChange={e =>
this.handleOnChange(
e,
hostIndex,
2,
softwareIndex
)
}
/>
</div>
);
} else {
const thirdLayerInputs = { ...lvl2Value };
return Object.entries(thirdLayerInputs).map(
([lvl3Key, lvl3Value]) => {
return (
<div>
<label>{lvl3Key}</label>{" "}
<input
name={lvl3Key}
value={lvl3Value}
onChange={e =>
this.handleOnChange(
e,
hostIndex,
3,
softwareIndex
)
}
/>
</div>
);
}
);
}
});
})}
<button onClick={() => this.addSoftwareToHost(hostIndex)}>
Add Software
</button>
</div>
);
} else {
return (
<div>
<label>{key}</label>{" "}
<input
value={value}
onChange={e => this.handleOnChange(e, hostIndex, 1)}
name={key}
/>
</div>
);
}
})}
</div>
);
});
};
addNewHost = () => {
const newHostObj = {
activityState: "",
platform: "",
pushDate: "",
name: "",
ip: "",
software: [
{
vulnerability: {
link: "",
desc: "",
cvss: "",
cve: ""
},
vulnerable: "",
cpe: "",
version: "",
vendor: "",
name: ""
}
]
};
this.setState({
newhosts: [...this.state.newhosts, newHostObj]
});
};
addSoftwareToHost = hostIndex => {
const { newhosts } = this.state;
const copiedHosts = [...newhosts];
const newSoftwareObj = {
vulnerability: {
link: "",
desc: "",
cvss: "",
cve: ""
},
vulnerable: "",
cpe: "",
version: "",
vendor: "",
name: ""
};
const updatedHosts = copiedHosts.map((host, index) => {
if (hostIndex === index) {
return {
...host,
software: [...host.software, newSoftwareObj]
};
} else {
return {
...host
};
}
});
this.setState({
newhosts: updatedHosts
});
};
handleSubmit = () => {
console.log(this.state.newhosts);
};
render() {
return (
<div>
{this.createNewHostsForm()}
<div style={{ margin: "25px 0px" }}>
{" "}
<button onClick={this.addNewHost}>Add Host</button>
</div>
<button onClick={this.handleSubmit}>Click to Log Hosts</button>
</div>
);
}
}
Upvotes: 0
Reputation: 1057
I think you have this data
state = {
newhosts : [{hostdata1}, {hostdata2}]
}
function addHostDescription = (selectHostIp) => {
const copyState = [...this.state.newhosts];
const hostIndex = copyState.findIndex(host => host.ip === selectHostIp);
copyState[hostIndex] = {...copyState[hostIndex], description : 'description content'};
this.setState({
newhosts : copyState
})
}
function addNewSoftware = (selectHostIp, newSoftware) => {
const copyState = [...this.state.newhosts];
const hostIndex = copyState.findIndex(host => host.ip === selectHostIp);
copyState[hostIndex].software.push(newSoftware);
this.setState({
newhosts : copyState
})
}
function addNewHost = (newHost) => {
const copyState = [...this.state.newhosts];
copyState.push(newHost);
this.setState({
newhosts : copyState
})
}
Upvotes: 2