class CreateEventForm extends Component {
constructor(props) {
super(props)
this.state = {
fields: {
name: '',
location: '',
description: '',
datetime: '',
},
friendsInEvent: [],
},
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
const { checked, value } = e.target
let { friendsInEvent } = { ...this.state }
if (checked) {
friendsInEvent = [...friendsInEvent, value]
} else {
friendsInEvent = friendsInEvent.filter(el => el !== value)
}
this.setState({ friendsInEvent }, () => console.log(this.state))
}
render() {
const { friends, createEvent, addFriendsToEvent } = this.props
const { fields: { name, location, description, datetime } } = this.state
const setter = propName => event => {
const nextFields = { ...this.state.fields }
nextFields[propName] = event.target.value
this.setState({ fields: nextFields })
}
return (
<div {...cssForm}>
<div>
<Label label="Event Name" />
<Field onChange={setter('name')} />
<Label label="Event Date/Time" />
<Field onChange={setter('datetime')} type="datetime-local" />
<Label label="Event Location" />
<Field onChange={setter('location')} />
<Label label="Event Description" />
<Field onChange={setter('description')} />
<SubHeader title="Add Friends to the Event..." />
<div>
{friends
.mapEntries(([friendId, frn]) => [
friendId,
<div key={friendId}>
<input
value={friendId}
type='checkbox'
onChange={this.handleChange}
defaultChecked={false} />
{frn.firstName} {frn.lastName}
</div>,
])
.toList()}
</div>
<Link to="/">
<Button style="blue" name="Done" onClick={() => createEvent(this.state.fields)} />
</Link>
</div>
</div>
)
}
}
export default CreateEventForm
上面的代码可以正常工作并存储所有正确的值。但是我想在fields {}内移动friendsInEvent []。看起来像:
super(props)
this.state = {
fields: {
name: '',
location: '',
description: '',
datetime: '',
friendsInEvent: [],
},
},
this.handleChange = this.handleChange.bind(this);
}
我怎样才能做到这一点?我尝试的所有内容都会破坏handleChange(e)函数或使用friendsInEvent数组覆盖字段{}。
我假设我在this.state.field中移动数组后必须更改handleChange(e)函数中的值?
另外,有没有办法合并我的两个函数setter和handleChange(e)?我将它们分开,因为它们处理两种不同的类型(字符串和数组)。
感谢。
答案 0 :(得分:1)
从外观上看,您需要对handleChange
进行以下更改:
handleChange(e) {
const { checked, value } = e.target;
// Ensure that you're destructuring from fields
let { friendsInEvent } = { ...this.state.fields };
if (checked) {
friendsInEvent = [...friendsInEvent, value];
} else {
friendsInEvent = friendsInEvent.filter(el => el !== value)
}
// You need to take a copy of state, and then supply a new copy
// of the the fields property which takes a copy of the old fields
// property, and overwrites the friendsInEvent with the new data
this.setState({
...this.state,
fields: {...this.state.fields, friendsInEvent }
}, () => console.log(this.state));
}
答案 1 :(得分:0)
为什么不能通过以下方式完成此操作。
handleChange(e) {
const { checked, value } = e.target
let { friendsInEvent } = { ...this.state }
if (checked) {
friendsInEvent = [...friendsInEvent, value]
} else {
friendsInEvent = friendsInEvent.filter(el => el !== value)
}
let object = {};
object.name = this.state.name;
object.location = this.state.location;
object.description = this.state.description;
object.datetime = this.state.datetime;
object.friendsInEvent = friendsInEvent;
this.setState({
fields: object
})
}
永远不要在render中进行setState。你不应该在render中做setState。事件处理程序应在render方法之前处理,但不在render内部处理。尽量避免在render中进行setState。
const setter = propName => event => {
const nextFields = { ...this.state.fields }
nextFields[propName] = event.target.value
this.setState({ fields: nextFields })
}