反应嵌套数组 [英] React Nested Array

查看:91
本文介绍了反应嵌套数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need to be able to combine this into one function. There are 2 separate arrays...

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

和...

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

基本上,这是因为我有一个将2个功能串联在一起的按钮,它必须在行类(MDBRow)之外,这样UI才不会中断.

Basically, this is because I have a button which concatenates the 2 functions and it has to be outside the row class (MDBRow) so the UI doesn't break.

<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函数...

This is the handleAddTelephone function...

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

};

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

and the Constructor looks like this...

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

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

Can I nest one array inside the other? I'm not sure how to do this so any advice appreciated. Thanks.

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

These are the 2 telephone functions which need to be 1 function... I have updated with new nested array for each

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

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

My constructor now looks like this...

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

推荐答案

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

Although I still don't quite understand how your UI "breaks" (video won't load for me), I hope I can help. Basically the short answer about trying to map two arrays singly is that you can't (well, shouldn't), but with some assumptions about the two array's length always being equal and the order is the same between the two, then you can map over the first array and use the passed index from the map function to access the second.

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

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

I think the better solution is to keep only a single array in state to map over in the first place.

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

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

If you also really want only a single change handler (I recommend they be separate), you can adopt a redux action/reducer type handler that accepts an object as a parameter that has all the data you need to update an array entry (index, update type, value). Here's a pretty clean example, but requires a bit of "action" setup when called:

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}`}
/>

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

Below I've created a few working sandbox demos:

  • 双电话数据数组,单个更改(动作/缩减程序")处理程序,单独的添加/删除功能,使用索引访问器的单个映射传递到第二个数组:
  • 单个电话数据阵列,单个更改处理程序,单独的添加/删除,单个映射传递:
  • 使用react useReducer,单个数组,reducer处理添加/删除/更新,单个映射传递:
  • Dual telephone data arrays, single change ("action/reducer") handler, separate add/remove functions, single map pass using index accessor to second array:
  • Single telephone data array, single change handler, separate add/remove, single map pass:
  • Use react useReducer, single array, reducer handles add/remove/update, single map pass:

我已经包含了代码文档,但是如果有任何不清楚的地方,请告诉我,我可以清理这些演示.

I've included code documentation but if anything is unclear please let me know and I can clean up these demos.

这篇关于反应嵌套数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆