【问题标题】:React Nested Array反应嵌套数组
【发布时间】:2023-04-01 00:00:02
【问题描述】:

我需要能够将其组合成一个功能。有 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: ""
        };
    }
}

我可以将一个数组嵌套在另一个数组中吗?我不知道如何做到这一点,所以任何建议表示赞赏。谢谢。

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

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 个示例数组中获得的单个数组,将会更容易理解
  • 您是否想要一个这样的数组:telephone: [{ type: "...", phone: "..."}, ...]?我不认为你必须诚实有什么问题。你想完成什么?
  • 您可以在此处看到它破坏了 UI,因为该函数需要围绕 Row 类进行包装。这对于 2 个功能是不可能的。 screencast.com/t/HksUkk7g3G 我会尝试建议的。谢谢。
  • 我想目前尚不清楚 UI 是如何中断的,也不清楚您要求什么或您的预期结果应该是什么。现在听起来好像您只需要一个处理程序来处理两个更新案例。
  • @DrewReese 我回来了,是的,你是对的,我需要一个处理程序,所以当我调用 handleAddTelephone 函数时,我可以调用“电话”而不是电话类型和电话。请看我的截屏视频,它显示了当我调用 handleAddTelephone screencast.com/t/HksUkk7g3G 时会发生什么

标签: arrays reactjs nested concat


【解决方案1】:

虽然我仍然不太了解您的 UI 是如何“中断”的(我无法加载视频),但我希望我能提供帮助。 基本上,关于尝试单独映射两个数组的简短答案是您不能(嗯,不应该),但是假设两个数组的长度始终相等且顺序相同在两者之间,然后您可以映射第一个数组并使用从映射函数传递的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 action/reducer 类型的处理程序,它接受一个对象作为包含更新数组条目所需的所有数据(索引、更新类型、值)的参数。这是一个非常干净的示例,但在调用时需要一些“动作”设置:

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

下面我创建了一些沙盒演示:

  • 双电话数据数组、单个更改(“action/reducer”)处理程序、单独的添加/删除函数、使用索引访问器到第二个数组的单个映射传递:
  • 单个电话数据数组、单个更改处理程序、单独添加/删除、单个映射传递:
  • 使用 react useReducer,单个数组,reducer 处理添加/删除/更新,单个映射传递:

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

【讨论】:

  • 感谢您抽出宝贵时间回复。尽管您的某些代码看起来更干净,但我确实提出了一个解决方案,尤其是选择选项。明天我会好好看看。我使用的解决方案在这篇帖子stackoverflow.com/questions/56805133/…
  • 很高兴。如果你觉得它有帮助,我不介意你回馈接受我的回答。
【解决方案2】:

是的,绝对是这样的:

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

【讨论】:

  • 谢谢。我现在已经用这个更新了我的原始帖子并更新了 2 个电话功能。我将如何创建 1 个地图功能而不是 2 个?这个简短的视频应该有助于解释我试图实现的目标以及 UI 是如何中断的。 screencast.com/t/qg8ccYPmrKJ1
猜你喜欢
  • 2020-08-04
  • 1970-01-01
  • 2019-06-02
  • 1970-01-01
  • 1970-01-01
  • 2023-02-16
  • 2017-08-04
  • 2018-12-17
  • 2019-01-07
相关资源
最近更新 更多