ΠΡΠ»ΠΈ Π²Ρ Π·Π½Π°Π΅ΡΠ΅, ΠΊΠ°ΠΊ ΡΠ΅ΡΠΈΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ, ΡΠ΄Π΅Π»Π°ΠΉΡΠ΅ Π·Π°ΠΏΡΠΎΡ Π½Π° ΠΏΠ΅ΡΠ΅Π½ΠΎΡ.
@types/react
, ΠΈ Ρ ΠΌΠ΅Π½Ρ Π²ΠΎΠ·Π½ΠΈΠΊΠ»ΠΈ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ.Definitions by:
Π² index.d.ts
), ΡΡΠΎΠ±Ρ ΠΎΠ½ΠΈ ΠΌΠΎΠ³Π»ΠΈ ΡΠ΅Π°Π³ΠΈΡΠΎΠ²Π°ΡΡ.ΠΡΠ»ΠΈ Π²Ρ Π½Π΅ ΡΠΊΠ°ΠΆΠ΅ΡΠ΅ Π°Π²ΡΠΎΡΠΎΠ², Π²ΠΎΠΏΡΠΎΡ Π±ΡΠ΄Π΅Ρ ΠΏΡΠΎΠΈΠ³Π½ΠΎΡΠΈΡΠΎΠ²Π°Π½.
Π― Π½Π΅ ΠΌΠΎΠ³Ρ Π²ΡΠ·Π²Π°ΡΡ setState
Ρ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠΌ, ΡΠΎΠ·Π΄Π°Π½Π½ΡΠΌ ΠΈΠ· ΠΈΠΌΠ΅Π½ΠΈ Π²ΡΡΠΈΡΠ»ΡΠ΅ΠΌΠΎΠ³ΠΎ ΡΠ²ΠΎΠΉΡΡΠ²Π° Ρ ΡΠΈΠΏΠΎΠ±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΡΡ:
type State = {
username: string,
password: string
};
type StateKeys = keyof State;
class A extends React.Component<{}, State> {
dynSetState(key: StateKeys, value: string) {
this.setState({
[key]: value // Error here. Pretty sure key is in StateKeys
});
}
}
ΠΠ½Π΅ ΠΈΠ·Π²Π΅ΡΡΠ½ΠΎ ΠΎ # 18365 ΠΈ ΠΎΠ±Ρ ΠΎΠ΄Π½ΠΎΠΌ ΠΏΡΡΠΈ Π² https://github.com/DefinitiTyped/DefinitiTyped/issues/18365#issuecomment -351868649. ΠΠ΄Π½Π°ΠΊΠΎ ΠΏΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ ΠΎΠ±Ρ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΡΡΠΈ Typescript Π½Π΅ Π²ΡΠ΄Π°Π΅Ρ ΠΎΡΠΈΠ±ΠΊΡ, ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ Π΄ΠΎΠ»ΠΆΠ΅Π½:
dynLooselySetState(key: string, value: string) {
this.setState(prevState => ({
...prevState,
[key]: value // No error here, but can't ensure that key is in StateKeys
}));
}
ΠΡΠΎ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠ΅ ΡΠ°ΠΌΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡΠ°, ΡΠΈΠΏΡ, Π²ΡΠ²Π΅Π΄Π΅Π½Π½ΡΠ΅ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Π²ΡΡΠΈΡΠ»Π΅Π½Π½ΡΡ
ΠΊΠ»ΡΡΠ΅ΠΉ ΡΠ²ΠΎΠΉΡΡΠ², Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡ ΡΠΈΠΏΡ ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΡ, ΠΎΠ½ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅Ρ ΡΠΎΠ»ΡΠΊΠΎ string
, number
, symbol
ΠΈΠ»ΠΈ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Π½ΠΈΡ
. 3, Π΅ΡΠ»ΠΈ ΠΎΠ½ ΠΎΠ±Π½Π°ΡΡΠΆΠΈΠ²Π°Π΅Ρ, ΡΡΠΎ ΡΡΠΎ ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ Π»ΡΠ±ΠΎΠ³ΠΎ ΠΈΠ· Π½ΠΈΡ
, ΠΎΠ½ ΠΏΡΠΎΡΡΠΎ ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄ΠΈΡ Π΅Π³ΠΎ Π² ΠΎΠ±ΡΠΈΠΉ ΡΠΈΠΏ string
. ΠΠ±Ρ
ΠΎΠ΄Π½ΠΎΠΉ ΠΏΡΡΡ Π·Π΄Π΅ΡΡ - ΠΏΡΠΈΠ½ΡΠ΄ΠΈΡΡ ΠΎΠ±ΡΠ΅ΠΊΡ:
dynSetState(key: StateKeys, value: string) {
this.setState({
[key]: value
} as Pick<State, keyof State>)
}
ΠΡΠΎ Π²ΡΠ΅ ΡΠ°Π²Π½ΠΎ ΠΏΡΠΈΠ²Π΅Π΄Π΅Ρ ΠΊ ΠΎΡΠΈΠ±ΠΊΠ΅, Π΅ΡΠ»ΠΈ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π½Π΅ Π²Ρ ΠΎΠ΄ΠΈΡ Π² Π½Π°Π±ΠΎΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΡΡ ΡΠΈΠΏΠΎΠ² Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ ΡΠ²ΠΎΠΉΡΡΠ², Π½ΠΎ Π½Π΅ Π²ΡΠ΄Π°ΡΡ ΠΎΡΠΈΠ±ΠΊΡ, Π΅ΡΠ»ΠΈ ΠΊΠ»ΡΡΠΈ Π½Π΅ Π²Ρ ΠΎΠ΄ΡΡ Π² Π½Π°Π±ΠΎΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΡΡ ΠΊΠ»ΡΡΠ΅ΠΉ ΡΠ²ΠΎΠΉΡΡΠ².
ΠΈΠΌΠ΅Π½Π½ΠΎ ΡΠΎ, ΡΡΠΎ @ferdaber, Ρ ΠΎΡΡ IMHO ΡΠ°ΠΊΠΈΠ΅ Π²Π΅ΡΠΈ, ΠΊΠ°ΠΊ ΡΡΠΎ, Π½Π΅ ΠΎΡΠ΅Π½Ρ "Ρ ΠΎΡΠΎΡΠΈΠΉ ΡΠ°Π±Π»ΠΎΠ½", Π² ΡΠ΅Π»ΠΎΠΌ Π²Ρ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΏΡΠ΅Π΄ΠΏΠΎΡΠ΅ΡΡΡ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΠ°Π±Π»ΠΎΠ½Π° ΠΎΠ±ΡΠ°ΡΠ½ΠΎΠ³ΠΎ Π²ΡΠ·ΠΎΠ²Π°, ΠΊΠΎΡΠΎΡΡΠΉ ΡΠ½ΠΎΠ²Π° ΠΏΡΠΈΠ΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΡΡΡ Π»ΡΡΡΠΈΡ ΠΏΡΠ°ΠΊΡΠΈΠΊ, ΡΠ°ΠΊΠΈΡ ΠΊΠ°ΠΊ ΠΈΠ·Π²Π»Π΅ΡΠ΅Π½ΠΈΠ΅ ΡΡΠΎΠ³ΠΎ ΠΎΠ±ΡΠ°ΡΠ½ΠΎΠ³ΠΎ Π²ΡΠ·ΠΎΠ²Π° Π²Π½Π΅ ΠΊΠ»Π°ΡΡΠ° Π² ΡΠΈΡΡΡΡ ΠΏΡΠΎΡΡΡΡ Π΄Π»Ρ ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΡΡΠ½ΠΊΡΠΈΡ :)
Π₯ΠΎΡΠΎΡΠΈΠΉ:
class C extends Component<{}, State> {
updateState(key: StateKeys, value: string) {
this.setState((prevState) => ({
...prevState,
[key]: value,
}));
}
}
ΠΡΡΡΠ΅:
const updateState = <T extends string>(key: keyof State, value: T) => (
prevState: State
): State => ({
...prevState,
[key]: value
})
class C extends Component<{}, State> {
doSomething(){
this.setState(updateState('password','123124'))
}
}
Π― Π½Π΅ Π½Π°ΡΠ΅Π» ΡΠ²ΡΠ·Π°Π½Π½ΠΎΠΉ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ Ρ ΡΡΠΈΠΌ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠ΅ΠΌ Π² ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΈ ΠΌΠ°ΡΠΈΠ½ΠΎΠΏΠΈΡΠ½ΠΎΠ³ΠΎ ΡΠ΅ΠΊΡΡΠ°. ΠΡΡΡ Π»ΠΈ ΡΠ°Π½Ρ, ΡΡΠΎ Π²Ρ Π·Π½Π°Π΅ΡΠ΅, ΠΎΠ±ΡΡΠΆΠ΄Π°Π»ΠΎΡΡ Π»ΠΈ ΡΡΠΎ (ΠΈ Π³Π΄Π΅) Π² ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΠΈ ΠΌΠ°ΡΠΈΠ½ΠΎΠΏΠΈΡΠ½ΠΎΠ³ΠΎ ΡΠ΅ΠΊΡΡΠ°? Π ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΌ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½ΠΎ, Π΅ΡΡΡ Π»ΠΈ ΠΊΠ°ΠΊΠΈΠ΅-ΡΠΎ ΠΏΠ»Π°Π½Ρ ΡΠ΅ΡΠΈΡΡ ΡΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ Π² Π±ΡΠ΄ΡΡΠΈΡ
Π²Π΅ΡΡΠΈΡΡ
ΠΌΠ°ΡΠΈΠ½ΠΎΠΏΠΈΡΠ½ΠΎΠ³ΠΎ ΡΠ΅ΠΊΡΡΠ°.
Π‘ΠΏΠ°ΡΠΈΠ±ΠΎ!
ΠΠΎΡ ΠΎΠ±ΡΡΠΆΠ΄Π΅Π½ΠΈΠ΅, ΠΏΡΠΈΠΌΠ΅ΡΠ°Π½ΠΈΡ ΠΏΠΎ Π΄ΠΈΠ·Π°ΠΉΠ½Ρ ΠΎΡ ΠΊΠΎΠΌΠ°Π½Π΄Ρ TS ΠΈ ΠΏΠΎΠΏΡΡΠΊΠ° ΠΈΡΠΏΡΠ°Π²ΠΈΡΡ ΡΡΠΎ (ΠΊΠΎΡΠΎΡΠΎΠ΅, ΠΊΠ°ΠΊ ΠΌΠ½Π΅ ΠΊΠ°ΠΆΠ΅ΡΡΡ, Π±ΡΠ»ΠΎ ΠΎΡΠΎΠ·Π²Π°Π½ΠΎ Π΄Π»Ρ Π±ΡΠ΄ΡΡΠ΅ΠΉ Π²Π΅ΡΡΠΈΠΈ):
https://github.com/Microsoft/TypeScript/issues/13948
https://github.com/Microsoft/TypeScript/issues/18155
https://github.com/Microsoft/TypeScript/pull/21070
Π ΡΠ°ΠΌΠΎΠΌ Π΄Π΅Π»Π΅, Ρ ΠΏΡΡΠ°ΡΡΡ ΡΠ΄Π΅Π»Π°ΡΡ ΡΡΠΎ-ΡΠΎ Π²ΡΠΎΠ΄Π΅ ΡΡΠΎΠ³ΠΎ: https://reactjs.org/docs/forms.html#handling -multiple-inputs
ΠΡΠΎ ΡΠΏΡΠΎΡΡΠΈΡ ΡΠ°Π±ΠΎΡΡ Ρ ΡΠΎΡΠΌΠΎΠΉ Ρ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΠΌΠΈ Π²Ρ
ΠΎΠ΄Π°ΠΌΠΈ. ΠΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, ΠΌΠ½Π΅ Π²ΡΠ΅ Π΅ΡΠ΅ ΠΏΡΠΈΠ΄Π΅ΡΡΡ ΡΠ±Π΅Π΄ΠΈΡΡΡΡ, ΡΡΠΎ Π°ΡΡΠΈΠ±ΡΡ name - ΡΡΠΎ ΡΠΎ, ΡΡΠΎ ΠΌΡ ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌ, Π½ΠΎ ΠΏΠΎΡΠ»Π΅ ΡΡΠΎΠ³ΠΎ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΡ ΡΠΈΠΏΠΎΠ² Π΄ΠΎΠ»ΠΆΠ½Π° ΡΠ°Π±ΠΎΡΠ°ΡΡ.
ΠΠ½Π΅ ΠΏΡΠΈΡΠ»ΠΎΡΡ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ as unknown
ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ @ferdaber :
this.setState({
[key]: value
} as unknown as Pick<State, keyof State>)
ΠΡΠΎ ΠΏΡΠ΅Π΄ΡΠΏΡΠ΅ΠΆΠ΄Π°Π΅Ρ, Π΅ΡΠ»ΠΈ key
Π±ΡΠ»ΠΎ Π»ΠΎΠ³ΠΈΡΠ΅ΡΠΊΠΈΠΌ, Π½ΠΎ Π½Π΅ ΡΠΈΡΠ»ΠΎΠΌ!
ΠΠΎΡΡΠΎΠΌΡ Ρ Π²ΡΠ±ΡΠ°Π» ΡΡΠΎ Π±ΠΎΠ»Π΅Π΅ ΠΊΠΎΡΠΎΡΠΊΠΎΠ΅ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅:
this.setState<never>({
[key]: value
})
ΠΡΠΎ ΠΏΡΠ΅Π΄ΡΠΏΡΠ΅ΠΆΠ΄Π°Π΅Ρ, ΡΠ²Π»ΡΠ΅ΡΡΡ Π»ΠΈ key
Π»ΠΎΠ³ΠΈΡΠ΅ΡΠΊΠΈΠΌ ΠΈΠ»ΠΈ ΡΠΈΡΠ»ΠΎΠΌ.
ΠΠΎΡΠ΅ΠΌΡ https://github.com/DefinitiTyped/DefinitiTyped/issues/26635#issuecomment -400260278 ΡΠ°Π±ΠΎΡΠ°Π΅Ρ? Π― ΠΈΠΌΠ΅Ρ Π² Π²ΠΈΠ΄Ρ, ΡΡΠΎ ΠΊΠ»ΡΡ ΠΏΠΎ-ΠΏΡΠ΅ΠΆΠ½Π΅ΠΌΡ ΡΠΈΠΏ ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΡ?
ΠΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΡΡΠΎ ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ ΡΠ΅Π±Π΅
type IAction = {
[P in keyof IAppSettings]?: IAppSettings[P];
};
function reducer(state: IAppSettings, action: IAction) {
return {
...state,
...action,
};
}
ΠΡΡΡ Π»ΠΈ ΠΏΡΠΎΠ³ΡΠ΅ΡΡ Π² ΡΡΠΎΠΌ Π²ΠΎΠΏΡΠΎΡΠ΅?
Π― ΡΠΌΠΎΠ³ Π·Π°ΡΡΠ°Π²ΠΈΡΡ ΡΡΠΎ ΡΠ°Π±ΠΎΡΠ°ΡΡ
handleTextChange(name: keyof State, value: any) {
this.setState({
...this.state,
[name]: value
});
}
ΠΠ»Ρ Π΄ΡΡΠ³ΠΈΡ
, ΠΊΠΎΡΠΎΡΡΠ΅ ΡΠΌΠΎΡΡΡΡ Π½Π° ΡΡΠΎ ΠΈ ΠΏΡΡΠ°ΡΡΡΡ ΠΏΡΠΈΠΌΠ΅Π½ΠΈΡΡ Π΅Π³ΠΎ ΠΊ ΡΠ²ΠΎΠΈΠΌ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠΌ ΡΠΈΠΏΠ°ΠΌ ΡΠΎΡΡΠΎΡΠ½ΠΈΠΉ, ΠΎΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, ΡΡΠΎ ΡΠΈΠΏ value
Π² ΠΈΡΡ
ΠΎΠ΄Π½ΠΎΠΌ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΈ ΠΈ ΠΎΡΠ²Π΅ΡΠ°Ρ
ΡΠ°Π²Π΅Π½ ΡΠΎΠ»ΡΠΊΠΎ string
ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ Π²ΡΠ΅ ΡΠΈΠΏΡ ΡΠ²ΠΎΠΉΡΡΠ² Π² State
- ΡΡΠΎ string
. ΠΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π»ΡΡΡΠ΅ ΠΈΠ·Π±Π΅Π³Π°ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ any
ΠΈΠ»ΠΈ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΠΎΠ³ΠΎ ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½ΠΈΡ, ΠΊΠΎΠ³Π΄Π° Π·Π°Π΄Π΅ΠΉΡΡΠ²ΠΎΠ²Π°Π½Ρ Π΄ΡΡΠ³ΠΈΠ΅ ΡΠΈΠΏΡ, ΠΈ Π²ΠΌΠ΅ΡΡΠΎ ΡΡΠΎΠ³ΠΎ ΠΎΠ³ΡΠ°Π½ΠΈΡΠΈΠ²Π°ΡΡ ΡΠΈΠΏΡ ΡΠ°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, ΡΡΠΎΠ±Ρ ΡΠΈΠΏ value
ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΎΠ²Π°Π» Π΅Π³ΠΎ ΡΠΈΠΏΡ, ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅ΠΌΡ ΡΠΈΠΏΡ ΠΊΠ»ΡΡΠ°.
interface State {
name: string;
age: number;
}
type StateKeys = keyof State;
function dynSetState<K extends StateKeys>(key: K, value: State[K]) {
this.setState({ [key]: value }); // fails; if only this worked...
this.setState({ [key]: value } as Pick<State, K>); // clean cast works
this.setState((s, _) => ({ ...s, [key]: value })); // avoids cast, but changes js
}
dynSetState("name", "a"); // works as expected
dynSetState("name", 1); // fails as expected
dynSetState("age", "a"); // fails as expected
dynSetState("age", 1); // works as expected
ΠΠΎΡΠ΅ΠΌΡ # 26635 (ΠΊΠΎΠΌΠΌΠ΅Π½ΡΠ°ΡΠΈΠΉ) ΡΠ°Π±ΠΎΡΠ°Π΅Ρ? Π― ΠΈΠΌΠ΅Ρ Π² Π²ΠΈΠ΄Ρ, ΡΡΠΎ ΠΊΠ»ΡΡ ΠΏΠΎ-ΠΏΡΠ΅ΠΆΠ½Π΅ΠΌΡ ΡΠΈΠΏ ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΡ?
ΠΡΠΎ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ ΡΠΈΠΏ { ...prevState }
Π±ΡΠ΄Π΅Ρ Π² Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎΠΉ ΠΌΠ΅ΡΠ΅ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΎΠ²Π°ΡΡ State
, Π² ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΌ ΠΏΠΎΡΠΎΠΌΡ, ΡΡΠΎ Ρ Π½Π°Ρ Π΅ΡΡΡ ΠΏΠΎ ΠΊΡΠ°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅ΡΠ΅ Π²ΡΠ΅ ΡΠ²ΠΎΠΉΡΡΠ²Π° ΡΠΎΡΡΠΎΡΠ½ΠΈΡ. ΠΡΠΎ ΠΌΠΎΠΆΠ΅Ρ ΠΏΠΎΠΌΠΎΡΡ ΠΏΠΎΠ½ΡΡΡ, ΠΏΠΎΡΠ΅ΠΌΡ Π±Π΅Π· Π½Π΅Π³ΠΎ _Π½Π΅ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ_. ΠΠΎΡΠ΅Π½Ρ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ Π² ΡΠΎΠΌ, ΡΡΠΎ ΡΠΈΠΏ ΡΠΎΠ·Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡΠ΅ΠΊΡΠ°: { [key: K]: State[K] }
Π½Π΅Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ΅Π½; ΡΡΠΎ { [x: string]: State[K] }
ΠΊΠΎΡΠΎΡΡΠΉ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°ΡΡ ΠΊΠ»ΡΡ string
Π² keyof State
.
ΠΡΠΎΡΡΠΎ Π΄ΠΎΠ±Π°Π²Π»Ρ Π²
TL; DR: ΠΎΠΊΠΎΠ½ΡΠ°ΡΠ΅Π»ΡΠ½ΠΎΠ΅ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ Π²Π½ΠΈΠ·Ρ
Π Π°ΡΡΠΈΡΠ΅Π½Π½ΠΎΠ΅ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ Ρ ΠΎΡΠΈΠ±ΠΊΠ°ΠΌΠΈ ΠΊΠΎΠ½ΡΠΎΠ»ΠΈ:
type RegisterTypes = {
email: string;
password: string;
}
// ...
const [state, setState] = useState<RegisterTypes>({
email: "",
password: "",
});
// ...
const onChangeInput = (key: keyof RegisterTypes) => (event: React.ChangeEvent<HTMLInputElement>) => {
setState({
[key]: event.target.value
} as Pick<RegisterTypes, typeof key>);
};
// ...
<input type="email" onChange={onChangeInput('email')} value={state.email} />
Π₯ΠΎΡΡ ΡΡΠΎ Π΄Π°Π΅Ρ ΠΌΠ½Π΅ ΡΠ»Π΅Π΄ΡΡΡΡΡ ΠΎΡΠΈΠ±ΠΊΡ Π² ΠΊΠΎΠ½ΡΠΎΠ»ΠΈ:
Warning: A component is changing a controlled input of type password to be uncontrolled. Input elements should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component.
ΠΠ»ΡΡΠ΅ΡΠ½Π°ΡΠΈΠ²Π½ΠΎΠ΅ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ (ΠΎΠ±ΠΌΠ°Π½) Ρ ΠΎΡΠΈΠ±ΠΊΠ°ΠΌΠΈ ΠΊΠΎΠ½ΡΠΎΠ»ΠΈ:
Π ΡΠΎΠΆΠ΅ Π΄Π°Π΅Ρ ΠΏΡΠ΅Π΄ΡΠΏΡΠ΅ΠΆΠ΄Π΅Π½ΠΈΠ΅.
type RegisterTypes = {
[key: string]: string;
}
// ...
const onChangeInput = (key: string) => (event: React.ChangeEvent<HTMLInputElement>) => {
setState({
[key]: event.target.value
});
};
ΠΠΊΠΎΠ½ΡΠ°ΡΠ΅Π»ΡΠ½ΠΎΠ΅ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ Π±Π΅Π· ΠΎΡΠΈΠ±ΠΎΠΊ:
type RegisterTypes = {
email: string;
password: string;
}
// ...
const onChangeInput = (event: React.ChangeEvent<HTMLInputElement>) => {
const newState = { ...state };
newState[event.target.name as keyof RegisterTypes] = event.target.value;
setState(newState);
};
// ...
<input name="email" type="email" onChange={onChangeInput} value={state.email} />
Π‘Π°ΠΌΡΠΉ ΠΏΠΎΠ»Π΅Π·Π½ΡΠΉ ΠΊΠΎΠΌΠΌΠ΅Π½ΡΠ°ΡΠΈΠΉ
ΠΡΠΎ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠ΅ ΡΠ°ΠΌΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΎΡΠ°, ΡΠΈΠΏΡ, Π²ΡΠ²Π΅Π΄Π΅Π½Π½ΡΠ΅ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Π²ΡΡΠΈΡΠ»Π΅Π½Π½ΡΡ ΠΊΠ»ΡΡΠ΅ΠΉ ΡΠ²ΠΎΠΉΡΡΠ², Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡ ΡΠΈΠΏΡ ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΡ, ΠΎΠ½ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅Ρ ΡΠΎΠ»ΡΠΊΠΎ
string
,number
,symbol
ΠΈΠ»ΠΈ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Π½ΠΈΡ . 3, Π΅ΡΠ»ΠΈ ΠΎΠ½ ΠΎΠ±Π½Π°ΡΡΠΆΠΈΠ²Π°Π΅Ρ, ΡΡΠΎ ΡΡΠΎ ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ Π»ΡΠ±ΠΎΠ³ΠΎ ΠΈΠ· Π½ΠΈΡ , ΠΎΠ½ ΠΏΡΠΎΡΡΠΎ ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄ΠΈΡ Π΅Π³ΠΎ Π² ΠΎΠ±ΡΠΈΠΉ ΡΠΈΠΏstring
. ΠΠ±Ρ ΠΎΠ΄Π½ΠΎΠΉ ΠΏΡΡΡ Π·Π΄Π΅ΡΡ - ΠΏΡΠΈΠ½ΡΠ΄ΠΈΡΡ ΠΎΠ±ΡΠ΅ΠΊΡ:ΠΡΠΎ Π²ΡΠ΅ ΡΠ°Π²Π½ΠΎ ΠΏΡΠΈΠ²Π΅Π΄Π΅Ρ ΠΊ ΠΎΡΠΈΠ±ΠΊΠ΅, Π΅ΡΠ»ΠΈ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π½Π΅ Π²Ρ ΠΎΠ΄ΠΈΡ Π² Π½Π°Π±ΠΎΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΡΡ ΡΠΈΠΏΠΎΠ² Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ ΡΠ²ΠΎΠΉΡΡΠ², Π½ΠΎ Π½Π΅ Π²ΡΠ΄Π°ΡΡ ΠΎΡΠΈΠ±ΠΊΡ, Π΅ΡΠ»ΠΈ ΠΊΠ»ΡΡΠΈ Π½Π΅ Π²Ρ ΠΎΠ΄ΡΡ Π² Π½Π°Π±ΠΎΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΡΡ ΠΊΠ»ΡΡΠ΅ΠΉ ΡΠ²ΠΎΠΉΡΡΠ².