首页 > 解决方案 > 如何在 React 中映射另一个文件中的对象数组?

问题描述

我正在尝试重构我的代码,并且在这样做时,我正在提取一个项目并将其放入它自己的组件中。该MemberItem组件具有多个影响其渲染的功能状态,但是,当我开始传递道具时,组件会中断。我正在传递子组件所需的所有函数、属性和状态,但我仍然无法让它正确呈现。

// Members.js (Parent Component)

export const Members = () => {
  // BELOW ARE THE FUNCTIONS AND STATE THAT INFLUENCE THE CHILD COMPONENT
  const [memberName, setMemberName] = useState('')
  const [editingMemberName, setEditingMemberName] = useState(
    members.map(() => false)
  )
  
  // Update member name
  const editMemberName = async (_, index) => {
    let new_editing_members_state = members.map(() => false)
    new_editing_members_state[index] = true
    setEditingMemberName(new_editing_members_state)
  }
  
  // Cancel editing mode
  const cancelEditMemberName = async (_, index) => {
    let new_editing_members_state = members.map(() => false)
    new_editing_members_state[index] = false
    setEditingMemberName(new_editing_members_state)
  }

  // UPDATE name in database
  const updateMemberName = async (index, id) => {
    let new_editing_members_state = members.map(() => false)
    new_editing_members_state[index] = false
    setEditingMemberName(new_editing_members_state)
  }

  // BELOW, LOOPS OVER EACH ITEM
  const memberItems = members.map((member, index) => {
    return (
      <MemberItem
        member={member}
        index={index}
        editingMemberName={editingMemberName[index]}
        editMemberName={editMemberName}
        handleChangeName={handleChangeName}
        updateMemberName={updateMemberName}
        cancelEditMemberName={cancelEditMemberName}
        destroyMember={destroyMember}
      />
    )
  })

  return (
    // RENDER THE LIST OF ITEMS
    {memberItems}
  )
}

// Member.js (Child Component)
export const MemberItem = (
  member,
  index,
  editingMemberName,
  editMemberName,
  handleChangeName,
  updateMemberName,
  cancelEditMemberName,
  destroyMember
  ) => {
  
  return (
     <div
      key={member.id}
    >
      <div>
        {editingMemberName[index] ? (
          <input
            type="text"
            placeholder="Johnny Appleseed"
            onChange={handleChangeName}
          />
        ) : (
          <>
            <div>
              {member.name.substring(0, 1).toUpperCase()}
            </div>
            <h3>{member.name}</h3>
          </>
        )}
      </div>
      <div>
        {editingMemberName[index] ? (
          <button
            onClick={() => updateMemberName(index, member.id)}
          >
            <CgCheckO size=".75em" />
          </button>
        ) : (
          <button
            onClick={() => editMemberName(member.id, index)}
          >
            <FiTool size=".75em" />
          </button>
        )}
        <button>
          {editingMemberName[index] ? (
            <GiCancel
              onClick={() => cancelEditMemberName(member.id, index)}
              size=".75em"
            />
          ) : (
            <RiDeleteBinLine
              onClick={() => destroyMember(member.id)}
              size=".75em"
            />
          )}
        </button>
      </div>
    </div>
  )
}

目前,我收到了 的错误TypeError: editingMemberName is undefined和警告Each child in a list should have a unique "key" prop,但是如果您看到,我确实将 id 传递给了 key 属性。

标签: javascriptreactjscomponentsmappingchildren

解决方案


在 React 中,props 作为单个对象传递给函数组件。您的组件函数假定 props 作为单独的参数而不是在单个对象中传递。

固定组件定义(注意参数列表周围的括号):

MemberItem = ({
  member,
  index,
  editingMemberName,
  editMemberName,
  handleChangeName,
  updateMemberName,
  cancelEditMemberName,
  destroyMember
}) => { ... }

这种解包属性的方法称为对象解构


推荐阅读