[英]React - using nested objects as state with hooks to fill form data
我有一個嵌套的 object 作為 state 如下所示 -
const [userInfo, setUserInfo] = useState({
author:"",
user: {
name: 'rahul',
email: 'rahul@gmail.com',
phone: [{ primary: '8888888810' }, { alternate: '7777777716' }]
}
});
我想要 5 個輸入字段 - 作者、姓名、email、主要和備用字段,並且只想使用一個 handleChange() 方法來更改字段。
您可以在鏈接上找到我寫的代碼 - https://stackblitz.com/edit/react-ngpx7q
在這里,我無法弄清楚如何正確更新 state。 任何幫助將不勝感激。
由於這是一個面試問題,所以我會避免使用 3rd-party 庫。 您可以使用switch
語句來處理不同嵌套的state,即第二層的name
和email
和第三層的primary
和alternate
。
const handleChange = (e) => {
const { name, value } = e.target;
switch (name) {
case "name":
case "email":
setUserInfo((userInfo) => ({
user: {
...userInfo.user,
[name]: value
}
}));
break;
case "primary":
case "alternate":
setUserInfo((userInfo) => ({
user: {
...userInfo.user,
phone: userInfo.user.phone.map((el) =>
el.hasOwnProperty(name)
? {
[name]: value
}
: el
)
}
}));
break;
default:
// ignore
}
};
您可以使用 lodash set為深度嵌套的 object 分配值。 您需要將path
傳遞給輸入的name
道具。
import set from 'lodash/set'
const App = () => {
const [userInfo, setUserInfo] = useState({
author:"",
user: {
name: 'rahul',
email: 'rahul@gmail.com',
phone: [{ primary: '8888888810' }, { alternate: '7777777716' }]
}
});
const handleChange = (e) => {
// clone the state
const userInfoCopy = JSON.parse(JSON.stringify(userInfo));
set(userInfoCopy, e.target.name, e.target.value)
setUserInfo(userInfoCopy)
}
console.log(userInfo)
return (
<div>
<input
name="user.name"
onChange={handleChange}
/>
<input
name="user.phone.[0].primary"
onChange={handleChange}
/>
</div>
);
};
現在您可以使用單個handleChange
方法來更新 state 中的所有密鑰。
與其將電話視為數組的 object(我認為這不是一個好主意),不如將其視為單個 object,將主要和備用作為鍵值對
import React, { useState } from 'react';
import './style.css';
export default function App() {
const [userInfo, setUserInfo] = useState({
user: {
name: 'ravi',
email: 'ravi@gmail.com',
phone: {
primary: 345345345345,
alternate: 234234234234
}
}
});
const handleChange = e => {
console.log(e.target.name);
setUserInfo(prevState => {
return {
user: {
...prevState.user,
[e.target.name]: e.target.value,
phone: {
...prevState.user.phone,
...{ [e.target.name]: e.target.value }
}
}
};
});
};
const {
name,
email,
phone: { primary, alternate }
} = userInfo.user;
console.log(userInfo);
return (
<div className="App">
Name: <input name="name" value={name} onChange={e => handleChange(e)} />
<br />
Email:{' '}
<input name="email" value={email} onChange={e => handleChange(e)} />
<br />
Primary:{' '}
<input name="primary" value={primary} onChange={e => handleChange(e)} />
<br />
Alternate:{' '}
<input
name="alternate"
value={alternate}
onChange={e => handleChange(e)}
/>
<br />
</div>
);
}
這基於您的原始數據(其中 phone 是一個對象數組):
const handleChange = e => {
let name = e.target.name;
if (['name', 'email'].includes(name)) {
setUserInfo(prevState => {
return {
user: {
...prevState.user,
[name]: e.target.value,
}
};
});
} else {
setUserInfo(prevState => {
return {
user: {
...prevState.user,
phone: name === 'primary' ?
[prevState.user.phone.find(e => Object.keys(e).includes('alternate')), {[name]: e.target.value}] :
[prevState.user.phone.find(e => Object.keys(e).includes('primary')), {[name]: e.target.value}]
}
};
});
}
};
我復制粘貼你的代碼,只編輯你的 handleChange
import React, { useState } from 'react';
import './style.css';
export default function App() {
const [userInfo, setUserInfo] = useState({
user: {
name: 'ravi',
email: 'ravi@gmail.com',
phone: [{ primary: '9999999990' }, { alternate: '9999998880' }]
}
});
const handleChange = e => {
console.log(e.target.name);
let arrPhone = userInfo.user.phone;
(e.target.name == 'primary' || e.target.name == 'alternate' )
&& arrPhone.map(x => (x.hasOwnProperty(e.target.name)) && (x[e.target.name] = e.target.value))
console.log(arrPhone)
setUserInfo(prevState => {
return {
user: {
...prevState.user,
[e.target.name]: e.target.value,
phone: arrPhone
}
};
});
};
const {
name,
email,
phone: [{ primary }, { alternate }]
} = userInfo.user;
console.log(userInfo);
return (
<div className="App">
Name: <input name="name" value={name} onChange={handleChange} />
<br />
Email: <input name="email" value={email} onChange={handleChange} />
<br />
Primary: <input name="primary" value={primary} onChange={handleChange} />
<br />
Alternate:{' '}
<input name="alternate" value={alternate} onChange={handleChange} />
<br />
</div>
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.