Мне нужно поддерживать массив объектов, который хранится в объекте состояния. В основном мне нужно помещать каждый объект в этот массив всякий раз, когда я нажимаю кнопку "Добавить". Это должно в основном хранить этот объект в массиве.
Также я не могу получить правильные значения, когда пытаюсь отправить? Где я ошибаюсь?
В основном структура, которую я хочу, такова:
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, в onAdd получите все входные значения из события, поместите их в объект (например, {name: e.input.name.value...} и установите его для пользователей (который будет массивом)
@Roy.B Не могли бы вы просто отредактировать onAdd?
@velsonjr Я добавил ответ, см. Ниже



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
Я боюсь, не!
почему ты такой?
просто добавить ключи, которые вы хотите обновить в состоянии, в операторе return внутри метода setState
Что нужно исправить: -
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'] и сопоставить их в функции рендеринга, таким образом, вам нужно будет написать форму один раз, и любое поле может быть добавлено.
Надеюсь, это поможет!!!
Не могли бы вы дать реализацию машинописного текста, похоже, это дает много ошибок! Спасибо
Пробовал это через this.setState({user: {name '', email: '', phone: ''}}); } в конце onAdd().
@velsonjr — обновлен код с возможностью очистки полей.
Почему в handleChangeEvent вы устанавливаете для пользователей новый объект, содержащий свойство учетной записи, если это массив пользователей?