Форма в React и TypeScript с СУХОЙ ручкой изменения - PullRequest
0 голосов
/ 02 февраля 2019

Я ищу лучший способ управления состоянием формы в React с помощью TypeScript.Моя простая форма имеет два значения: login и password поля.Я реализую интерфейс IState для состояния формы и метод DRY handleChange для сохранения нового значения в состоянии без воссоздания функции при каждом выполнении render().

interface IState {
  login: string;
  password: string;
}

class LoginForm extends React.Component<{}, IState> {
  public state = {
    login: "",
    password: "",
  };

  public render() {
    const { login, password } = this.state;
    return (
      <form>
        <input name="login" value={login} onChange={this.handleChange}/>
        <input name="password" value={password} onChange={this.handleChange} type="password"/>
      </form>
    );
  }

  private handleChange = (e: React.FormEvent<HTMLInputElement>) => {
    const { name, value } = e.currentTarget;
    const n = name as keyof IState;
    // @ts-ignore
    this.setState({
      [n]: value,
    });
  }
}

Я использую атрибут name нативного HTML для хранилищаИмя поляПеременная n будет иметь только значение login или password.Любое другое значение невозможно.Могу ли я сказать TypeScript, что переменная n имеет тип "login" | "password" литералы?TypeScript рассматривает n как string переменную типа, даже если я использую:

const n = name as keyof IState;

или

const n = name as "login" | "password";

Затем, когда я удаляю // @ts-ignore, я получаю ошибку:

Type error: Argument of type '{ [x: string]: string; }' is not assignable to parameter of type 'IState | Pick<IState, "login" | "password"> | ((prevState: Readonly<IState>, props: Readonly<IProps>) => IState | Pick<IState, "login" | "password"> | null) | null'.
Type '{ [x: string]: string; }' is missing the following properties from type 'Pick<IState, "login" | "password">': login, password  TS2345

но без ошибок при жестком коде:

const n = "login";

Есть ли способ заставить "login" | "password" тип переменной n?Или любое другое решение для DRY handleChange без проблем оптимизации и чистого TypeScript?

1 Ответ

0 голосов
/ 02 февраля 2019

Мы можем использовать Pick, чтобы убедиться, что вы устанавливаете ключ, определенный в вашем интерфейсе IState.

Pick - set state

private handleChange = (e: React.FormEvent<HTMLInputElement>) => {
    const { name, value } = e.currentTarget;
    this.setState({
        [name]: value
    } as Pick<IState, keyof IState>);
};

Или вы можете использовать Partial, что сделает все ваши ключи состояния необязательными.

class App extends React.Component<{}, Partial<IState>> {
    // ... rest of component
}
...