React + Typescript: получение ошибки типа при динамическом задании значений в обработчике изменений - PullRequest
0 голосов
/ 04 апреля 2019

Я пытаюсь создать форму динамически на основе массива объектов.

Цель состоит в том, чтобы динамически создавать учетные записи пользователей по нажатию кнопки «Добавить пользователя» и передавать весь объект состояния пользователей в серверную часть.

Получение этой ошибки ' Элемент неявно имеет тип' any 'потому что тип' {name: string;возраст: строка;} 'не имеет подписи индекса '.

Я новичок в реакции!Помощь будет оценена.

Что я делаю не так?

import * as React from "react";

interface State{
  users:User[]
}
interface Props{

}
interface User{
  name:string,
  age:number;
}

class App extends React.Component<Props,State> {

   state = {
      users: [{name:"", age:""}],
   }

   handleChange = (value:number,event  : React.ChangeEvent<HTMLInputElement>) => {
    let users = [...this.state.users];
    console.log(event.target.value);
    users[value][event.target.name] = event.target.value;
    this.setState({ users }, () => console.log(this.state.users))
   }

   addUser = () => {    
    this.setState((prevState) => ({
      users: [...prevState.users, {name:"", age:""}],
    }));
   }

   handleSubmit = (e:any) => { 
       e.preventDefault();
       console.log(this.state.users) 
   }

   render() {
     let { users} = this.state
     return (
      <form onSubmit={this.handleSubmit} >
        <button onClick={this.addUser}>Add new cat</button>
        {
          users.map((val, id)=> {
            return (
              <div key={id}>
                <input
                  type="text"
                  name="name"                 
                  value={users[id].name}                   
                  onChange = {(e) =>this.handleChange(id,e)}
                />

                <input
                  type="text"
                  name="age"
                  value={users[id].age}                  
                  onChange = {(e) => this.handleChange(id,e)}
                />
              </div>
            )
          })
        }
        <input type="submit" value="Submit" /> 
      </form>
    )
  }
}
export default App;

Ответы [ 2 ]

1 голос
/ 04 апреля 2019

Тип event.target.value является строковым и необязательно 'name' | 'age', поэтому при вызове:

users[value][event.target.name] = event.target.value;

Машинопись не может быть уверена, что users[value] будет иметь этот индекс.Поэтому вы можете либо изменить интерфейс пользователя:

interface User {
    name:string,
    age:number;
    [key: string]: string | number
}

, либо проверить, соответствует ли ключ ожидаемому:

const keyName = event.target.name
if (keyName === 'name' || keyName === 'age') {
    users[value][keyName] = event.target.value;
}
1 голос
/ 04 апреля 2019

Во-первых, интерфейс пользователя неверен.age приводится к числу, и вы устанавливаете age в пустую строку "".

Во-вторых, когда вы используете Array.prototype.map, вы не используете index [id].Реализация вашей функции map () выглядит немного странно.Из MDN

Метод map () создает новый массив с результатами вызова предоставленной функции для каждого элемента в вызывающем массиве.

Подробнее окарта здесь

import * as React from "react";

interface Props{

}

interface User {
  name: string;
  age: number | string;
}

interface State {
  users: User[];
}

class App extends React.Component<Props, State> {
  constructor(props: Props) {
    super(props);
    this.state = {
      users: [{ name: "", age: "" }]
    };
  }

  handleChange = (value: number, event: React.ChangeEvent<HTMLInputElement>) => {
    let users = [...this.state.users];
    users[value][event.target.name] = event.target.value;
    this.setState({ users }, () => console.log(this.state.users));
  };

  addUser = () => {
    this.setState(prevState => ({
      users: [...prevState.users, { name: "", age: "" }]
    }));
  };

  handleSubmit = (e: any) => {
    e.preventDefault();
    console.log(this.state.users);
  };

  render() {
    const { users } = this.state;
    return (
      <form onSubmit={this.handleSubmit}>
        <button onClick={this.addUser}>Add new cat</button>
        {users.map((user, id) => {
          return (
            <div key={id}>
              <input
                type="text"
                name="name"
                value={user.name}
                onChange={e => this.handleChange(id, e)}
              />

              <input
                type="text"
                name="age"
                value={user.age}
                onChange={e => this.handleChange(id, e)}
              />
            </div>
          );
        })}
        <input type="submit" value="Submit" />
      </form>
    );
  }
}
export default App;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...