【问题标题】:Can I map within a map like this?我可以在这样的地图内映射吗?
【发布时间】:2021-01-21 08:49:13
【问题描述】:

我正在学习 react/jsx,但遇到了一个难题。

我想通过尝试在地图中创建地图来“简化”,我以为我知道自己在做什么,但显然它不喜欢它。

我有以下对象:

defaultState = {
  userName: "",
  firstName: "",
  lastName: "",
  email: "",
  bio: "",
  country: "",
  notifications: [
    {
      label: "Newsletter",
      value: "newsletter",
      checked: false,
    },
    {
      label: "Updates",
      value: "updates",
      checked: false,
    },
    {
      label: "Reports",
      value: "reports",
      checked: false,
    },
  ]
};

本质上,我想在 defaultState 数据中制作通知地图。这样我就有了一张包含以下信息的卡片

  1. firstName={user.firstName}
  2. lastName={user.lastName}
  3. 用户名={user.userName}
  4. email={user.email}
  5. bio={user.bio}
  6. {user.notifications[0].value} ={user.notifications[0].checked}
  7. {user.notifications[1].value} ={user.notifications[1].checked}
  8. {user.notifications[2].value} ={user.notifications[2].checked}

所以它看起来像这样

  • 用户名:ausername123
  • 名字:A.
  • 姓:W.
  • 邮箱:blahblah@gmail.com
  • 简历:有说明
  • 报纸通知:真
  • 更新通知:错误
  • 报告通知:真

到目前为止,我已经写了以下的地图

{this.state.users.map((user) => {
  return(
    <User
      key={user.userName}
      firstName={user.firstName}
      lastName={user.lastName}
      userName={user.userName}
      email={user.email}
      bio={user.bio}
      country={user.country}
      {user.notifications.map((n) => n.value = n.checked)}
    />
  )
})}

然而行 {user.notifications.map((n) => n.value = n.checked)} 出现以下错误

SyntaxError: Unexpected token, expected "..." (31:33)

31 | {user.notifications.map((n) => n.value = n.checked)} | ^ 32 | /> 33 | ) 34 | })}

由于一个请求,这是我试图在 User.js 上运行的。本质上我想创建三个附加的道具标记

  • 时事通讯
  • 更新
  • 报告 它们恰好是通知[].label,我想根据选中的复选框给它们一个真或假的值。

const User = ({userName, firstName, lastName, email, bio, country, newsletter, updates, reports}) => (
        <Component>
            <Header>User Details of {firstName} {lastName}</Header>
            <Field>
                <Text>
                    <strong>Username:</strong>
                </Text>
                <Item>{userName}</Item>
            </Field>
            <Field>
                <Text>
                    <strong>Email:</strong>
                </Text>
                <Item>{email}</Item>
            </Field>
            <Field>
                <Text>
                    <strong>Bio:</strong>
                </Text>
                <Item>{bio}</Item>
            </Field>
            <Field>
                <Text>
                    <strong>Country:</strong>
                </Text>
                <Item>{country}</Item>
            </Field>
            <Field>
                <Text>
                    <strong>Newsletter:</strong>
                </Text>
                <Item>{newsletter}</Item>
            </Field>
            <Field>
                <Text>
                    <strong>Updates:</strong>
                </Text>
                <Item>{updates}</Item>
            </Field>
            <Field>
                <Text>
                    <strong>Reports:</strong>
                </Text>
                <Item>{reports}</Item>
            </Field>
        </Component>
    );

【问题讨论】:

  • 您必须将通知分配给您将在User 组件中处理的道具;您应该将{user.notifications.map((n) =&gt; n.value = n.checked)} 更改为notifications={user.notifications.map((n) =&gt; n.value = n.checked)}
  • @secan 把它写成答案
  • @slebetman,当然,没问题;我不认为它具有正确答案的“尊严”,因为它不是解决某些晦涩问题的方法,并且可以在官方文档中找到或推断出来。

标签: javascript reactjs jsx


【解决方案1】:

您必须将通知分配给您将在用户组件中处理的道具;你应该改变

{user.notifications.map((n) =&gt; n.value = n.checked)}

notifications={user.notifications.map((n) =&gt; ({[n.value]: n.checked}))}

那么User 组件中的notifications 属性将如下所示:

[
  { newsletter: false },
  { updates: false },
  { reports: false } 
]

如果你想要一个对象,你应该使用reduce:

notifications={user.notifications.reduce((obj, n) =&gt; ({ ...obj, [n.value]: n.checked })), {}}

会给你

{
  newsletter: false,
  updates: false,
  reports: false
}

但实际上,由于您已经拥有 user.notifications,因此最符合逻辑和最直接的做法是将其作为 prop (notifications={user.notifications}) 传递,并在必要时在 User 组件中对其进行操作。

[更新]

使用User 组件的代码更新您的问题后,这应该可以作为一个完整的解决方案:

在父组件中:

//...
{this.state.users.map(user => (
  <User
    key={user.userName}
    firstName={user.firstName}
    lastName={user.lastName}
    email={user.email}
    bio={user.bio}
    country={user.country}
    notifications={user.notifications}
  />
))}
//...

或者,如果您要传递 user 对象的全部或大部分属性,则只需传递整个对象

//...
{this.state.users.map(user => (
  <User
    key={user.userName}
    user={user}
  />
))}
//...

在用户组件中:

const User = ({userName, firstName, lastName, email, bio, country, notifications}) => {
  return (
    <Component>
      <Header>User Details of {firstName} {lastName}</Header>
      <Field>
        <Text><strong>Username:</strong></Text>
        <Item>{userName}</Item>
      </Field>
      <Field>
        <Text><strong>Email:</strong></Text>
        <Item>{email}</Item>
      </Field>
      <Field>
        <Text><strong>Bio:</strong></Text>
        <Item>{bio}</Item>
      </Field>
      <Field>
        <Text><strong>Country:</strong></Text>
        <Item>{country}</Item>
      </Field>
      {notifications.map(n => (
        <Field>
          <Text><strong>{n.label}</strong></Text>
          <Item>{ n.checked ? 'true' : 'false' }</Item>
        </Field>
      ))}
    </Component>
  );
};

或者,如果您从父级传递整个用户对象:

const User = ({user}) => {
  const {userName, firstName, lastName, email, bio, country, notifications} = user;
  return (
    <Component>
      <Header>User Details of {firstName} {lastName}</Header>
      <Field>
        <Text><strong>Username:</strong></Text>
        <Item>{userName}</Item>
      </Field>
      <Field>
        <Text><strong>Email:</strong></Text>
        <Item>{email}</Item>
      </Field>
      <Field>
        <Text><strong>Bio:</strong></Text>
        <Item>{bio}</Item>
      </Field>
      <Field>
        <Text><strong>Country:</strong></Text>
        <Item>{country}</Item>
      </Field>
      {notifications.map(n => (
        <Field>
          <Text><strong>{n.label}</strong></Text>
          <Item>{ n.checked ? 'true' : 'false' }</Item>
        </Field>
      ))}
    </Component>
  );
};

【讨论】:

  • 嗯,它没有崩溃,这是一个好的开始。我将尝试找出未显示真/假值的其余部分。
  • 好吧,你使用的内部地图没有意义:n.value 是一个字符串,n.check 是一个布尔值;它们永远不会相等...特别是如果您尝试使用分配(=)而不是比较(=====)来比较它们
  • 我也更新了解决该问题的答案
  • 我尝试了 toString() n.checked 的值,这样它就会显示为类似于名为报纸的道具,即通知[0].value 将包含“true”的字符串语句或“假”。 Idk 如果它是这样工作的。
  • @AlbertWang,不,它不是这样工作的。如果您使用User 组件的代码更新您的问题,它会更容易为您提供帮助
猜你喜欢
  • 2019-11-21
  • 1970-01-01
  • 2022-11-04
  • 1970-01-01
  • 1970-01-01
  • 2015-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多