我正在设置一个表单,在表单中有一个材料 UI 选择字段范围从 1 到 50。每次用户选择一个数字时,我将如何动态显示/呈现多个文本字段"名字和姓氏",每个文本字段中都有钩子?
前任。 如果用户从选择框中的选项中选择"3",则预期将呈现 3 个文本字段"名字和姓氏"。
这是我到目前为止尝试过的,我知道如何使用特定的文本字段创建钩子,但我不知道我是否会依赖于用户的选择。
const primary_guest_firstname = useForm('');
const primary_guest_lastname = useForm('');
const primary_guest_adult = useForm(1);
function useForm(init){
const [ value, setValue ] = useState(init);
function handleOnChange(e){
setValue(e.target.value);
}
return {
value,
onChange: handleOnChange
}
}
/** sample of select text field with options from 1 - 50... **/
<TextField
select
variant="outlined"
required
margin="dense"
fullWidth
value={primary_guest_adult.value}
onChange={primary_guest_adult.onChange}
id="guest"
label="Adult ( > 12 years)"
name="guest"
>
<MenuItem value="1">1</MenuItem>
<MenuItem value="2">2</MenuItem>
<MenuItem value="3">3</MenuItem>
...
<MenuItem value="50">50</MenuItem>
</TextField>
/** I should render dynamic textfield here...
if the user selected "3", there should be 3 textfields
generated here with hook.. **/
<TextField
variant="outlined"
required
margin="dense"
fullWidth
id="firstName"
label="First Name"
name="firstName"
value={primary_guest_firstname.value}
onChange={primary_guest_firstname.onChange}
/>
<TextField
variant="outlined"
required
margin="dense"
fullWidth
id="lastName"
label="Last Name"
name="lastName"
value={primary_guest_lastname.value}
onChange={primary_guest_lastname.onChange}
/>
感谢您的帮助:)谢谢!
您可以通过在状态数组中创建必需值的数组来执行此操作。
您将拥有一组状态,而不是单个状态,需要相应地设置和读取这些状态。
演示:
const { render } = ReactDOM;
const { useState, useEffect } = React;
function useForm(init){
const [ value, setValue ] = useState(init);
function handleOnChange(e){
setValue(e.target.value);
}
return {
value,
onChange: handleOnChange
}
}
function useForms(reqNum) {
const initial = [...Array(reqNum)].map(()=>({ firstName: "", lastName: "" }));
const [values, setValues] = useState(initial);
function handleChange(event, name, changedIndex) {
const { target: { value }} = event;
setValues(values => values.map((val, index) => {
if(changedIndex === index) {
return {
...val,
[name]: value,
}
}
return val;
}));
}
function handleNumChange(changedNum) {
const changedValues = [...Array(+changedNum)].map(()=>({ firstName: "", lastName: "" }));
setValues(changedValues);
}
return {
values,
handleChange,
handleNumChange,
}
}
const NameFields = ({ values }) => {
return (
<div>
{values.map((value, index) => (
<div key={index}>
<input placeholder={`First Name ${index+1}`} value={value.firstName} onChange={(e) => handleChange(e, "firstName", index)} />
<input placeholder={`Last Name ${index+1}`} value={value.lastName} onChange={(e) => handleChange(e, "lastName", index)} />
</div>
))}
</div>
);
}
const App = () => {
const options = [1,2,3,4,5];
const {value: numberOfAdults, onChange: setNumberOfAdults} = useForm(1);
const { values, handleChange, handleNumChange } = useForms(numberOfAdults);
useEffect(() => {
handleNumChange(numberOfAdults);
}, [numberOfAdults]);
return (
<main>
<select value={numberOfAdults} onChange={setNumberOfAdults}>
{options.map((option)=>(
<option value={option} key={option}>{option}</option>
))}
</select>
<NameFields values={values} />
</main>
);
}
render(<App />, document.getElementById("root"));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root" />