簡體   English   中英

Typescript & ReactJS 如何動態設置狀態

[英]Typescript & ReactJS How To Dynamically Set State

我將此接口定義為我的狀態:

interface State {
  id: string;
  name: string;
  description: string;
  dimensionID: string;
  file: File | null;
  operator: string;
  isFormValid: boolean;
  filename: string;
};

我有一個簡單的更改處理程序:

  update = (event: React.FormEvent<HTMLInputElement>): void => {
    const { name, value } = event.currentTarget;
    this.setState({ [name]: value });
  };

然而,這個錯誤被拋出:

Error:(109, 19) TS2345: Argument of type '{ [x: string]: string; }' is not assignable to parameter of type 'State | Pick<State, "id" | "name" | "description" | "dimensionID" | "file" | "operator" | "isFormValid" | "filename"> | ((prevState: Readonly<State>, props: Readonly<Props>) => State | Pick<...>)'.
  Type '{ [x: string]: string; }' is not assignable to type '(prevState: Readonly<State>, props: Readonly<Props>) => State | Pick<State, "id" | "name" | "description" | "dimensionID" | "file" | "operator" | "isFormValid" | "filename">'.
    Type '{ [x: string]: string; }' provides no match for the signature '(prevState: Readonly<State>, props: Readonly<Props>): State | Pick<State, "id" | "name" | "description" | "dimensionID" | "file" | "operator" | "isFormValid" | "filename">'.

我的問題是:如何像我的更改處理程序嘗試那樣動態設置狀態? 這個處理程序用於表單的不同部分,所以我不知道我需要更新哪個狀態鍵。

更新:解決方案來自這篇文章

  update = (event: React.FormEvent<HTMLInputElement>): void => {
    const { name, value } = event.currentTarget;
    this.setState(prevState => ({
      ...prevState,
      [name]: value,
    }))
  };

作品!

常量被擴展為字符串。 你用的是哪個版本的TS?

你像這樣投射它,但這不是一個好習慣:

this.setState({
  [name]: value
} as Pick<State, keyof State>);

與此問題相關的錯誤:

最優選的溶液澆鑄。

this.setState({[name]: value} as {[P in keyof State]: State[P]})
// or
this.setState({[name]: value} as Pick<State, keyof State>)

setState 與傳播先前的狀態

this.setState((prevState) => ({ ...prevState, [name]: value }));

這不會檢查類型。 對於任何被困在轉譯中的人來說,這只是一個快速的解決方法。

this.setState<never>({[name]: value})

相關鏈接

反應 setState

Github Tim Roes 評論

例如。

update = (name: string, event: React.FormEvent<HTMLInputElement>): void => {
    const { value } = event.currentTarget;
    this.setState({ [name]: value });
  };

<input onChange={this.update.bind(null, 'first_name')} value={this.state.first_name} />

您可以使用in keyof關鍵字從 IState 對象中解構鍵/值。

創建你的 React 狀態:

interface IState { "email" : string; }

創建一個表單類型,將鍵解構為 K,值解構為 T[K]:

type FormState<T> = { [K in keyof T]: T[K] };
// T represents your IState
// to get the key use: [K in keyof T]
// to reference the value use: T[K]

然后將 IState 作為泛型類型參數傳遞給 FormState 類型:

FormState<IState>

現在您可以更新狀態,將其轉換為上面的 FormState:

this.setState({ [formStateItem]: (e.target.value as any) } as FormState<IState>);

在處理程序中,它可能如下所示:

handleChange = <T, K extends keyof IState>(formStateItem: K) => {
    return (e: ChangeEvent<HTMLInputElement>) => {
        this.setState({ [formStateItem]: (e.target.value as any) } as FormState<IState>);
    }
};

最后你可以像這樣在你的 JSX 中使用:

onChange={this.handleChange("email")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM