对象参数在传递给 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 })
这就是嵌套的原因。
我在 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 })
这就是嵌套的原因。