简体   繁体   English

如何在状态ReactJS中声明带有对象的数组

[英]How to declare an array with objects in the state ReactJS

I am wondering how to make new blank array with objects in the state and how to add element in it with setState. 我想知道如何在状态下使用对象创建新的空白数组,以及如何使用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. 在这里,我必须用您的函数替换此“ newState.push”,该函数将数据保存到状态。

I think you have this data 我想你有这个数据

state = {
   newhosts : [{hostdata1}, {hostdata2}]
}

add host description 添加主机描述

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
    })
}

add new software 添加新软件

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
    })
}

add new host 添加新主机

function addNewHost = (newHost) => {
    const copyState = [...this.state.newhosts];
    copyState.push(newHost);
    this.setState({
        newhosts : copyState
    })
}

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 考虑一下我为您制作的沙箱: 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: 此代码将向您展示如何:

  • Create a new host object and the corresponding inputs for the user to fill. 创建一个新的host对象和相应的输入,以供用户填写。
  • Update a single host object, it's first layer such as fields activityState , platform , etc. 更新单个主机对象,它是第一层,例如字段activityStateplatform等。
  • Update a single software object inside a host, including the inner vulnerability object and outer-fields such as vulnerable , cpe , etc. 更新主机内部的单个software对象,包括内部vulnerability对象和外部字段,例如vulnerablecpe等。
  • Adding a new, additional software object to a host. 将新的附加software对象添加到主机。 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 . hostssoftware任何组合填写表格,完成后点击Click to Log Hosts按钮以打印最终state

The code: 编码:

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>
    );
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM