对象参数在传递给 React 中的构造函数后变得嵌套

Object argument becomes nested after being passed to constructor in React

我在 Full Stack Open 上做第 2 部分时无法理解一个非常奇怪的错误。 简而言之:将对象传递给组件会将对象变成嵌套对象。 即:

entries.map(entry => { console.log(entry); return <PhonebookEntry  props={entry} />})

App.js

function PhonebookEntry(props) {
  console.log(props)
  //rest of code
}

index.js 未按预期工作。

当运行时,浏览器的控制台显示如下:

Object { name: "Derp", surname: "Derpington", phone: "012345", address: "2012 Street" }
App.js:33

Object { props: {…} }
props: Object { name: "Derp", surname: "Derpington", phone: "012345", … }
<prototype>: Object { … }
PhonebookEntry.js:2

这是App.js

import { useState } from 'react'
import PhonebookEntry from './PhonebookEntry.js'

export default function App() {

  function handleAddEntry(e) {
    e.preventDefault()
    setEntries(entries.concat({
      name: newName,
      surname: newSurname,
      phone: newPhone,
      address: newAddress
    }))
  }

  const [entries, setEntries] = useState([
    {
      name: "Derp",
      surname: "Derpington",
      phone: "012345",
      address: "2012 Street"
    }
  ])
  const [newName, setNewName] = useState('')
  const [newSurname, setNewSurname] = useState('')
  const [newPhone, setNewPhone] = useState('')
  const [newAddress, setNewAddress] = useState('')

  return (
    <div>
      <h1>Phonebook</h1>
      <ul>
        {entries.map(entry => { console.log(entry); return <PhonebookEntry  props={entry} />})}
      </ul>
      <form onSubmit={handleAddEntry}>
        Name: <input value={newName} onChange={(e) => setNewName(e.target.value) }/><br></br>
        Surname: <input value={newSurname} onChange={(e) => setNewSurname(e.target.value)}/><br></br>
        Phone: <input value={newPhone} onChange={(e) => setNewPhone(e.target.value)}/><br></br>
        Address: <input value={newAddress} onChange={(e) => setNewAddress(e.target.value)}/><br></br>
        <button type="submit">Add</button>
      </form>
    </div>
  )
  }

这里是 PhonebookEntry.js:

function PhonebookEntry(props) {
  console.log(props)
  return (
      <li>
        <div>
          Name: {`${props.surname}, ${props.name}`}
        </div>
        <div>
          Phone: {props.phone}
        </div>
        <div>
          Address: {props.address}
        </div>
      </li>
    )
}

export default PhonebookEntry

这不是错误,这是一个功能。

你可以这么想:

<Component foo={bar} />

像这样:

Component({ foo: bar })

现在,它比这更复杂一点,但这确实是 JSX 中的 props 所代表的。

所以,就像我们传播的方式一样parameters/arguments,我们也有传播道具:

<PhonebookEntry {...entry} />

这与(大致)相同:

PhonebookEntry({ ...entry })

https://reactjs.org/docs/jsx-in-depth.html#spread-attributes

回到你原来的例子,

<PhonebookEntry props={entry} />

只是

PhonebookEntry({ props: entry })

这就是嵌套的原因。