我正在尝试创建一个由输入动态填充的不可变状态数组。但是,我无法创建新状态并将其添加到我的people
数组中。这样做的正确方法是什么?下面是该问题的jsfiddle演示的链接。
链接演示:http://jsfiddle.net/560fyjnp/1536/
映射并返回附加数组:
appendPerson() {
let newPerson = {
name: '',
age: '',
school: ''
};
this.setState((prevState) => ({
people: prevState.people.concat([newPerson])
}));
}
处理来自输入的更改:
handleChange(e) {
this.setState({[e.target.name]: e.target.value})
}
示例输入:
Name: <input name="name" value={person.name} onChange={this.props.handleChange} />
映射状态并显示有状态字符串:
{this.state.people.map((person, index) =>
<div key={index}>
Name: {person.name}<br />
Age: {person.age}<br />
School: {person.school}
<hr/>
</div>
)}
答案 0 :(得分:2)
您需要更新handleChange
函数以接受将作为参数传入的索引。您应该bind
Inputs
中的更改处理程序传入索引:
handleChange(index, e) {
// Make a shallow clone of your state array
const people = [...this.state.people];
// Update the object at the passed in index with the property name and value
people[index] = {...people[index], [e.target.name]: e.target.value};
this.setState({
people
});
}
完整示例:
class Inputs extends React.Component {
constructor(props) {
super(props);
this.state = {}
}
render() {
return (
<div>
{this.props.people.map((person, index) =>
<div key={index}>
Name: <input name="name" value={person.name} onChange={this.props.handleChange.bind(this, index)} /><br/>
Age: <input name="age" value={person.age} onChange={this.props.handleChange.bind(this, index)} /><br/>
School: <input name="school" value={person.school} onChange={this.props.handleChange.bind(this, index)} />
<hr />
</div>
)}
<button onClick={ this.props.appendPerson }>Add Another Person</button>
</div>
);
}
}
class People extends React.Component {
constructor(props) {
super(props);
this.state = {
people: [{
name: 'Jerry',
age: '20',
school: 'Fun University'
}]
}
this.handleChange = this.handleChange.bind(this);
this.appendPerson = this.appendPerson.bind(this);
}
handleChange(index, e) {
const people = [...this.state.people];
people[index] = {...people[index], [e.target.name]: e.target.value};
this.setState({
people
});
}
appendPerson() {
let newPerson = {
name: '',
age: '',
school: ''
};
//this.setState({ people: this.state.people.concat([newPerson])});
this.setState((prevState) => ({
people: prevState.people.concat([newPerson])
}));
}
render() {
return (
<div>
<h1>Add Person:</h1>
<Inputs
people={this.state.people}
appendPerson={this.appendPerson}
handleChange={this.handleChange}
/>
<h1>People:</h1>
{this.state.people.map((person, index) =>
<div key={index}>
Name: {person.name}<br />
Age: {person.age}<br />
School: {person.school}
<hr/>
</div>
)}
</div>
);
}
}
ReactDOM.render(
<People/>,
document.getElementById('container')
);
答案 1 :(得分:1)
您必须将索引传递给handleChange。小提琴:http://jsfiddle.net/560fyjnp/1551/
class Inputs extends React.Component {
constructor(props) {
super(props);
this.state = {}
}
render() {
return (
<div>
{this.props.people.map((person, index) =>
<div key={index}>
Name: <input name="name" data-index={index} value={person.name} onChange={this.props.handleChange} /><br/>
Age: <input name="age" data-index={index} value={person.age} onChange={this.props.handleChange} /><br/>
School: <input name="school" data-index={index} value={person.school} onChange={this.props.handleChange} />
<hr />
</div>
)}
<button onClick={ this.props.appendPerson }>Add Another Person</button>
</div>
);
}
}
class People extends React.Component {
constructor(props) {
super(props);
this.state = {
people: [{
name: 'Jerry',
age: '20',
school: 'Fun University'
}]
}
this.handleChange = this.handleChange.bind(this);
this.appendPerson = this.appendPerson.bind(this);
}
handleChange(e) {
this.setState((prevState)=>{
prevState.people[parseInt(e.target.getAttribute('data-index'))][e.target.name]= e.target.value;
return prevState;
})
}
appendPerson() {
let newPerson = {
name: '',
age: '',
school: ''
};
//this.setState({ people: this.state.people.concat([newPerson])});
this.setState((prevState) => ({
people: prevState.people.concat([newPerson])
}));
}
render() {
return (
<div>
<h1>Add Person:</h1>
<Inputs
people={this.state.people}
appendPerson={this.appendPerson}
handleChange={this.handleChange}
/>
<h1>People:</h1>
{this.state.people.map((person, index) =>
<div key={index}>
Name: {person.name}<br />
Age: {person.age}<br />
School: {person.school}
<hr/>
</div>
)}
</div>
);
}
}
ReactDOM.render(
<People/>,
document.getElementById('container')
);
答案 2 :(得分:1)
您需要稍微更改代码才能使其正常工作。
查看我的解决方案。 JSFiddle demo
以下是input
元素中的onChange函数应该如何。
<input name="name" value={person.name} onChange={({ target }) => this.props.handleChange(index, target.name, target.value)} />
然后有handleChange
功能。
handleChange(peopleIndex, name, value) {
this.setState(prevState => {
const editedPeople = prevState.people[peopleIndex];
editedPeople[name] = value;
return {
people: [
...prevState.people.slice(0, peopleIndex),
editedPeople,
...prevState.people.slice(peopleIndex + 1)
]
};
});
}
你有它。与没有data-*
属性的输入链接的独立数据结构。
希望这有帮助。