Как подтолкнуть объект к массиву, который является объектом состояния, реагировать с помощью Typescript

Мне нужно поддерживать массив объектов, который хранится в объекте состояния. В основном мне нужно помещать каждый объект в этот массив всякий раз, когда я нажимаю кнопку "Добавить". Это должно в основном хранить этот объект в массиве.

Также я не могу получить правильные значения, когда пытаюсь отправить? Где я ошибаюсь?

В основном структура, которую я хочу, такова:

users= [
        {"name":"xxx","email":"yyy","phone":"656"},
        {"name":"yyy","email":"xxx","phone":"55"}
       ];
import * as React from 'react';
interface IState{
    users : Account[];
}
interface Account{
  name: string;
  email: string;
  phone: string
}

export default class App extends React.Component<{},IState> {

    constructor(props:any){
       super(props);
       this.state= { 
                         users: []
                   }
    }


  handleChangeEvent = ( event: React.ChangeEvent<HTMLInputElement>) => {
   this.setState({
    users:{
      ...this.state.users,
      [event.target.name]:event.target.value
    }
    })
  }

  onAdd = () => {
     this.setState((prevState) => ({
     users: [...prevState.users],
    }));
    console.info(this.state.users); // Unable to get the proper info
  }

  render(){
   <React.Fragment>
     <form onSubmit = {this.onAdd}>
       <input type = "text" onChange = {(e:any) => this.handleChangeEvent(e)} name = {"name"} />
       <input type = "text" onChange = {(e:any) => this.handleChangeEvent(e)} name = {"email"} />
       <input type = "text" onChange = {(e:any) => this.handleChangeEvent(e)} name = {"phone"} />
       <button type = "submit">Add</button>
      </form>
   </React.Fragment>
  }
}

Почему в handleChangeEvent вы устанавливаете для пользователей новый объект, содержащий свойство учетной записи, если это массив пользователей?

Draeken 29.04.2019 11:03

Возможный дубликат Реагировать - состояние не обновлено

maazadeeb 29.04.2019 11:06

вам не нужен handleChangeEvent, в onAdd получите все входные значения из события, поместите их в объект (например, {name: e.input.name.value...} и установите его для пользователей (который будет массивом)

Roy.B 29.04.2019 11:06

@Roy.B Не могли бы вы просто отредактировать onAdd?

joy08 29.04.2019 11:07

@velsonjr Я добавил ответ, см. Ниже

Roy.B 29.04.2019 11:38
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
1
5
2 032
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

export default class App extends React.Component<{},IState> {

state = {
      users: [],
      text: '',
}


  handleChangeEvent = ( event: React.ChangeEvent<HTMLInputElement>) => {
   this.setState({
    [e.target.name]: e.target.value
    })
  }

  onAdd = () => this.setState({
    users:[
          ...this.state.users,
          {
           e.target.name: e.target.value,
           e.target.email: e.target.value,
           e.target.phone: e.target.value
          }
    ]
  })

  render(){
   <React.Fragment>
     <form onSubmit = {this.onAdd}>
       <input type = "text" onChange = {(e:any) => this.handleChangeEvent(e)} name = {"name"} />
       <input type = "text" onChange = {(e:any) => this.handleChangeEvent(e)} name = {"email"} />
       <input type = "text" onChange = {(e:any) => this.handleChangeEvent(e)} name = {"phone"} />
       <button type = "submit">Add</button>
      </form>
   </React.Fragment>
  }
}

Вы устанавливаете свой users как массив, а затем конвертируете его в объект с помощью handleChangeEvent. Попробуйте проверить, работает ли это

вам не нужен handleChangeEvent, в onAdd получите все входные значения из события, поместите их в объект (например, {name: event.target.form.elements.name.value...} и установите его для пользователей (которые будут массив)

 export default class App extends React.Component{

    constructor(props:any){
       super(props);
       this.state = { 
             users: []
       }
    }

onAdd = (event) => {

 const user = {
   name: event.target.form.elements.name.value,
   email: event.target.form.elements.email.value,
   phone: event.target.form.elements.phone.value
  }
     this.setState({
     users: [...this.state.users, user]
    });

  }

  render(){
   <React.Fragment>
     <form onSubmit = {this.onAdd}>
       <input type = "text"  name = "name" />
       <input type = "text" name = "email" />
       <input type = "text" name = "phone" />
       <button type = "submit">Add</button>
      </form>
   </React.Fragment>
  }
}

затем, если вы войдете в this.state.users, вы получите нужную вам структуру

users= [
        {"name":"xxx","email":"yyy","phone":"656"},
        {"name":"yyy","email":"xxx","phone":"55"}
       ];

Обновите onAdd, как показано ниже, потому что метод setState обновляет состояние асинхронно, поэтому вы не можете получить состояние сразу после его вызова, но вы можете сделать это, используя обратный вызов в качестве второго аргумента в методе setState, который вызывается после того, как метод обновил состояние.

onAdd = () => {
  this.setState((prevState) => {
    const newUser = {}
    return {
      users: [...prevState.users, newUser],
    }
  }, () => {
    console.info(this.state.users)
  });
}

просто добавьте больше ключей для обновления в операторе return

Shridhar Sharma 29.04.2019 13:21

Я боюсь, не!

joy08 29.04.2019 13:39

почему ты такой?

Shridhar Sharma 29.04.2019 13:41

просто добавить ключи, которые вы хотите обновить в состоянии, в операторе return внутри метода setState

Shridhar Sharma 29.04.2019 14:15
Ответ принят как подходящий

Что нужно исправить: -

1) Вы используете только одну переменную состояния users для одного пользователя, а также для всех пользователей. Поэтому создайте две переменные состояния: одну для временного хранения данных для пользователя и переменную users для хранения данных всех пользователей.

2) Вы пытаетесь получить доступ к console.info(this.state.users); после setState, но его нет в обратном вызове, setState является асинхронным, он должен быть в обратном вызове setState.

3) Когда пользователь отправляет форму, страница обновляется, что является поведением приложения по умолчанию, нам нужно e.preventDefault(); переопределить это поведение.

4) Используйте состояние для отдельных текстовых полей ввода, чтобы вы могли применять проверку и т. д. В полях.

import * as React from "react";
import { render } from "react-dom";

interface IState {
  users : Account[],
  user: Account
}

interface Account{
  name: string;
  email: string;
  phone: string
}

class App extends React.Component<{}, IState> {
  constructor(props: any) {
    super(props);
    this.state = {
      users: [],
      user: {name: '', email:'', phone: ''}
    }
  }

  handleChangeEvent = (event: React.FormEvent<HTMLInputElement>) => {
    this.setState({
      user: {
        ...this.state.user,
        [event.currentTarget.name]: event.currentTarget.value
      }
    });
  };

  onAdd = (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    this.setState(
      { 
        users: [...this.state.users, this.state.user],
        user: {name:'', email: '', phone: ''}
      },
      () => {
        console.info("updated state", this.state.users);
      }
    );
  };

  public render() {
    const { name, email, phone } = this.state.user;
    return (
      <form onSubmit = {this.onAdd}>
        <input type = "text" onChange = {this.handleChangeEvent} value = {name} name = "name" />
        <input type = "text" onChange = {this.handleChangeEvent} value = {email} name = "email" />
        <input type = "text" onChange = {this.handleChangeEvent} value = {phone} name = "phone" />
        <button type = "submit">Add</button>
      </form>
    );
  }
}

render(<App />, document.getElementById("root"));

Область улучшений. Вы можете объявить массив полей, таких как fields = ['name', 'phone', 'email'] и сопоставить их в функции рендеринга, таким образом, вам нужно будет написать форму один раз, и любое поле может быть добавлено.

Надеюсь, это поможет!!!

Не могли бы вы дать реализацию машинописного текста, похоже, это дает много ошибок! Спасибо

joy08 29.04.2019 12:42

Пробовал это через this.setState({user: {name '', email: '', phone: ''}}); } в конце onAdd().

joy08 29.04.2019 13:10

@velsonjr — обновлен код с возможностью очистки полей.

tarzen chugh 29.04.2019 13:24

Другие вопросы по теме