反应嵌套数组

时间:2019-06-28 13:32:03

标签: arrays reactjs nested concat

我需要能够将其组合为一个功能。有2个单独的数组...

{this.state.telephoneType.map((telephoneType, ttidx) => ())}

和...

{this.state.telephone.map((telephone, tidx) => ())}

基本上,这是因为我有一个连接这2个功能的按钮,并且它必须在行类(MDBRow)之外,这样UI才不会中断。

<MDBRow className="grey-text no-gutters my-2">

    {this.state.telephoneType.map((telephoneType, ttidx) => (

        <MDBCol md="4" className="mr-2">
            <select
                key={ttidx}
                defaultValue={telephoneType.name}
                onChange={this.handleTelephoneTypeChange(ttidx)}
                className="browser-default custom-select">
                <option value="Mobile">Mobile</option>
                <option value="Landline">Landline</option>
                <option value="Work">Work</option>
            </select>
        </MDBCol>
    ))}

    {this.state.telephone.map((telephone, tidx) => (

        <MDBCol md="7" className="d-flex align-items-center">
            <input
                value={telephone.name}
                onChange={this.handleTelephoneChange(tidx)}
                placeholder={`Telephone No. #${tidx + 1}`}
                className="form-control"
            />
            <MDBIcon icon="minus-circle"
                className="mr-0 ml-2 red-text"
                onClick={this.handleRemoveTelephone(tidx)} />
        </MDBCol>

    ))}

</MDBRow>

<div className="btn-add" onClick={this.handleAddTelephone}>
    <MDBIcon className="mr-1" icon="plus-square" />
        Add Telephone
</div>

这是handleAddTelephone函数...

handleAddTelephone = () => {
    this.setState({
        telephone: this.state.telephone.concat([{ name: "" }]),
        telephoneType: this.state.telephoneType.concat([{ name: "" }])
    });

};

构造函数看起来像这样...

class InstallerAdd extends React.Component {
    constructor() {
        super();
        this.state = {
            role: "Installer",
            name: "",
            telephoneType: [{ name: "" }],
            telephone: [{ name: "" }],
            tidx: "",
            emailType: [{ email: "" }],
            email: [{ email: "" }],
            eidx: "",
            notes: ""
        };
    }
}

我可以将一个数组嵌套在另一个数组中吗?我不确定如何执行此操作,因此不胜感激。谢谢。

编辑: 这些是2个电话功能,必须是1个功能... 我已经为每个更新了新的嵌套数组

handleTelephoneChange = tidx => evt => {
    const newTelephone = this.state.telephone.type.map((telephone, tsidx) => {

        if (tidx !== tsidx) return telephone;
        return { ...telephone, name: evt.target.value };
    });
    this.setState({ telephone: newTelephone }, () => {
        // get state on callback
        console.log(this.state.telephone.number[tidx].name)
    }
    );
};

handleTelephoneTypeChange = ttidx => evt => {
    const newTelephoneType = this.state.telephone.number.map((telephoneType, ttsidx) => {
        if (ttidx !== ttsidx) return telephoneType;
        return { ...telephoneType, name: evt.target.value };
    });
    this.setState({ telephoneType: newTelephoneType }, () => {
        // get state on callback
        console.log(this.state.telephone.type[ttidx].name)
    }
    );
};

我的构造函数现在看起来像这样...

class InstallerAdd extends React.Component {
    constructor() {
        super();
        this.state = {
            role: "Installer",
            name: "",
            telephone: {
                type: [{ name: "" }],
                number: [{ name: "" }]
              },
            tidx: "",
            emailType: [{ email: "" }],
            email: [{ email: "" }],
            eidx: "",
            notes: ""
        };
    }

2 个答案:

答案 0 :(得分:0)

是的,绝对是这样:

telephone: {
  list: [1,2,3],
  type: [“foo”, “bar”, “baz”]
}

答案 1 :(得分:0)

尽管我仍然不太了解您的UI如何“崩溃”(视频不会为我加载),但希望我能为您提供帮助。  基本上,关于尝试单独映射两个数组的简短答案是您不能(嗯,不应该),但是在假设两个数组的长度始终相等且顺序相同的前提下在这两者之间,则可以映射第一个数组,并使用从map函数传递的index来访问第二个数组。

arrayA.map((itemFromA, index) => {
  // do stuff with item from A
  const itemFromB = arrayB[index];
  // do stuff with item from B
});

我认为更好的解决方案是首先只保留一个数组以进行映射。

state = {
  telephones: [], // { type: string, number: string }[]
}
...
state.telephones.map(({ type, number }, index) => {
  // do stuff with telephone type
  ...
  // do stuff with telephone number
});

如果您还真的只想一个变更处理程序(我建议它们是分开的),则可以采用redux动作/归约类型处理程序,将一个对象接受为一个具有更新数组条目所需的所有数据(索引,更新类型,值)的参数。这是一个非常干净的示例,但是在调用时需要一些“操作”设置:

changeHandler = (index, type) => e => {
  const newTelephoneData = [...this.state.telephones];
  newTelephoneData[index][type] = e.target.value;
  this.setState({ telephones: newTelephoneData });
}

<select
  value={type}
  onChange={this.telephoneChangeHandler(index, "type")}
>
  // options
</select>

...

<input
  value={number}
  onChange={this.telephoneChangeHandler(index, "number")}
  placeholder={`Telephone No. #${index + 1}`}
/>

下面,我创建了一些可运行的沙箱演示:

  • 双电话数据数组,单个更改(“动作/减少程序”)处理程序,单独的添加/删除功能,使用索引访问器的第二个映射传递到第二个数组: Edit nested-dual-array-update
  • 单个电话数据阵列,单个更改处理程序,单独的添加/删除,单个映射传递: Edit nested-single-array-update
  • 使用react useReducer,单个数组,reducer处理添加/删除/更新,单个映射传递: Edit nested-single-array-update-hooks

我已经提供了代码文档,但是如果不清楚,请告诉我,我可以清理这些演示。