#javascript #reactjs #typescript
Вопрос:
У меня здесь есть текстовое поле:
<TextFieldItem
primary="Barion ID"
required="**"
value={selectedOrganization?.barionId ?? ""}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
selectedOrganization.barionId = event.target.value;
setSelectedOrganization(selectedOrganization);
}}
onBlur={() => validateBarionId()}
disabled={
!selectedOrganizationId || !userFbId || editBarionIdIsDisabled
}
placeholder="e-mail"
helperText={barionIdHelperText}
/>
Здесь у меня есть переменная состояния:
const [selectedOrganization, setSelectedOrganization] = useState<
OrganizationOut | undefined
>(undefined);
export type OrganizationOut = {
name?: string;
barionId?: string;
И он сохраняет пустую строку, неважно, что я там пишу, она всегда пуста.
Когда раньше отображалась атомарная строка, она работала, но теперь, когда она завернута в объект, это не так. Ты знаешь, почему?
1 получил эту ошибку при использовании ОТВЕТА 1
./pages/[lang]/onboarding2.tsx:645:51
Type error: Argument of type '(preState: OrganizationOut | undefined) => { szamlazzhuSzamlaAgentKulcsTemp: string; name?: string | undefined; barionId?: string | undefined; barionIdTemp?: string | undefined; ... 18 more ...; urlPrefix?: string | undefined; }' is not assignable to parameter of type 'SetStateAction<OrganizationOut | undefined>'.
Type '(preState: OrganizationOut | undefined) => { szamlazzhuSzamlaAgentKulcsTemp: string; name?: string | undefined; barionId?: string | undefined; barionIdTemp?: string | undefined; ... 18 more ...; urlPrefix?: string | undefined; }' is not assignable to type '(prevState: OrganizationOut | undefined) => OrganizationOut | undefined'.
Call signature return types '{ szamlazzhuSzamlaAgentKulcsTemp: string; name?: string | undefined; barionId?: string | undefined; barionIdTemp?: string | undefined; szamlazzhuSzamlaAgentKulcs?: string | undefined; ... 17 more ...; urlPrefix?: string | undefined; }' and 'OrganizationOut | undefined' are incompatible.
The types of 'events' are incompatible between these types.
Type '{ [eventId: string]: EventOut; } | undefined' is not assignable to type '{ [eventId: string]: EventOut; }'.
Type 'undefined' is not assignable to type '{ [eventId: string]: EventOut; }'.
643 | selectedOrganization.szamlazzhuSzamlaAgentKulcsTemp =
644 | event.target.value;
> 645 | setSelectedOrganization((preState) => ({
| ^
646 | ...preState,
647 | szamlazzhuSzamlaAgentKulcsTemp: event.target.value!,
648 | }));
error Command failed with exit code 1.
Ответ №1:
Потому что вы неправильно настроили объект состояния.
setSelectedOrganization(preState => ({ ...preState, barionId: event.target.value }));
Вы можете прочитать подробную информацию в документах:
состояние — это ссылка на состояние компонента в момент применения изменения. Он не должен подвергаться прямой мутации. Вместо этого изменения должны быть представлены созданием нового объекта на основе входных данных из состояния и реквизитов.
Комментарии:
1. Спасибо, уоркс, не могли бы вы объяснить, почему, в чем разница?
2. Я добавил документ
3. спасибо, не могли бы вы помочь еще немного? Знаете ли вы, почему я получил сообщение об ошибке, прикрепленное к вопросу, когда я запускаю
yarn build
?
Ответ №2:
Никогда не изменяйте фактическое состояние. Состояние должно использоваться как значение только для чтения, которое представляет значение состояния, поддерживаемое React. Однако любые изменения в нем не изменяют фактическое состояние. Вот setState
для чего это нужно.
Во-вторых, React использует ===
сравнение, чтобы проверить, было ли изменено состояние. Когда вы передаете массив или объект setState
функции, она сравнивает их по ссылке, а не по значению. Это означает, что вам нужно создать новый объект или массив, а не использовать один и тот же:
const [state, setState] = useState({});
state.a = 5; // Mistake: never modify the actual state!
setState(state); // Mistake: setState will not update because reference is the same
Вместо этого вам нужно создать новый объект (или массив) из текущего состояния, изменить его, а затем, наконец, использовать его для setState
:
const [state, setState] = useState({});
const newState = {...state}; // Create a shallow copy of the state
newState.a = 5; // Modify the copy, and not the real state
setState(newState); // Set the state to the copy, that has a different reference