Я хочу сохранить информацию о нескольких входах, введенных в компоненты и Select, в одну переменную состояния, но у меня возникли проблемы с тем, чтобы заставить работать ниже.
Этот пример решен здесь для формы, но такое же решение, похоже, не работает для компонента antd Select. Есть два входа: имя и фамилия, которые я хочу запомнить. Приведенный ниже код не работает, потому что у e нет атрибута с именем name, что мне говорит консоль. Я также пробовал e.target.name и e.target.value, но получаю сообщение об ошибке, что e также не имеет атрибута, называемого target. Как правильно это сделать?
import React, { useState } from 'react';
import { Select } from 'antd';
const App = () =>{
const [varState, setVarState] = useState({firstName:'Jack', lastName:'Smith'});
const firstNameOptions = [ {label:'Jack', value:'Jack'}, {label:'Jill',value:'Jill'}, {label:'Bill',value:'Bill'} ];
const lastNameOptions = [ {label:'Smith', value:'Smith'}, {label:'Potter',value:'Potter'}, {label:'Bach',value:'Bach'} ];
const changeState = (e) => {
setVarState( prevState => ({ ...prevState, [e.name]: e.value}));
console.info(varState)
};
return ( <>
<div>
<Select name = {'firstName'} defaultValue = {'Pick One'} options = {firstNameOptions} onChange = {changeState} />
<Select name = {'lastName'} defaultValue = {'Pick One'} options = {lastNameOptions} onChange = {changeState} />
</div>
</>
);
}
export default App;
да, на самом деле у antd нет атрибута name
для полей ввода. antdesign напрямую дает выбранное значение, нам нужно сделать некоторые настройки, чтобы добиться этого.
Вот решение:
import React, { useState } from 'react';
import { Select } from 'antd';
const firstNameOptions = [ {label:'Jack', value:'Jack'}, {label:'Jill',value:'Jill'}, {label:'Bill',value:'Bill'} ];
const lastNameOptions = [ {label:'Smith', value:'Smith'}, {label:'Potter',value:'Potter'}, {label:'Bach',value:'Bach'} ];
const App = () =>{
const [varState, setVarState] = useState(null);
const changeState = (fieldName) => (value) => {
setVarState( prevState => ({ ...prevState, [fieldName]: value}));
console.info(varState)
};
return ( <>
<div>
<Select defaultValue = {'Pick One'} options = {firstNameOptions} onChange = {changeState('firstName')} />
<Select defaultValue = {'Pick One'} options = {lastNameOptions} onChange = {changeState('lastName')} />
</div>
</>
);
}
export default App;
Надеюсь, это поможет 😊
Кажется, что компонент Select отправляет значение вместо объекта событий. Итак, вы можете просто сделать закрытие и передать имя выбора. Кроме того, для утешения вы можете использовать useEffect, который утешает только при обновлении состояния. В противном случае вы могли бы увидеть предыдущее состояние, поскольку обновления состояния являются асинхронными. Ниже приведено рабочее решение.
import React, { useEffect, useState } from "react";
import { Select } from "antd";
const App = () => {
const [varState, setVarState] = useState({
firstName: "Jack",
lastName: "Smith"
});
const firstNameOptions = [
{ label: "Jack", value: "Jack" },
{ label: "Jill", value: "Jill" },
{ label: "Bill", value: "Bill" }
];
const lastNameOptions = [
{ label: "Smith", value: "Smith" },
{ label: "Potter", value: "Potter" },
{ label: "Bach", value: "Bach" }
];
// for consoling when the state updates
useEffect(() => {
console.info(varState);
}, [varState.firstName, varState.lastName]);
const changeState = (value, identifier) => {
// console.info(value, identifier);
setVarState((prevState) => ({ ...prevState, [identifier]: value }));
};
return (
<>
<div>
<Select
name = {"firstName"}
defaultValue = {"Pick One"}
options = {firstNameOptions}
onChange = {(val) => changeState(val, "firstName")}
/>
<Select
name = {"lastName"}
defaultValue = {"Pick One"}
options = {lastNameOptions}
onChange = {(val) => changeState(val, "lastName")}
/>
</div>
</>
);
};
export default App;
Быстрый вопрос: если я помещу console.info(varState) сразу после вызова setVarState, напечатанное значение будет на один шаг позади выбора, который я вижу в пользовательском интерфейсе. Вы знаете, почему это так? Разве мой вызов setVarState не должен уже изменить varState? Это та же проблема, что и в другом ответе.
Это потому, что setState — асинхронная функция. поэтому обновление происходит асинхронно и поэтому есть задержка. используя useEffect, мы гарантируем, что утешение происходит только тогда, когда происходит обновление состояния
Таким образом, вы в основном делаете changeState функцией, которая возвращает функцию. если вы передаете «firstName», он возвращает функцию изменения firstName и то же самое для «lastName». Одна проблема, которую я заметил, заключается в том, что этот подход, по-видимому, удерживает firstName и lastName на один шаг позади выбранных значений в пользовательском интерфейсе. Можете ли вы объяснить, почему?