Open evantianx opened 7 years ago
Never mutate
this.state
directly, as callingsetState()
afterwards may replace the mutation you made. Treatthis.state
as if it were immutable.
// 很危险的做法 ⚠️
updateState(event) {
const {name, value} = event.target;
let user = this.state.user; // this is a reference, not a copy...
user[name] = value; // so this mutates state 🙀
return this.setState({user});
}
Object.assign()
updateState(event) {
const {name, value} = event.target;
// 创建一个空对象并将 state.user 中所有属性赋予
let user = Object.assign({}, this.state.user);
user[name] = value;
return this.setState({user});
}
这个方法的弊端在于——对低级浏览器兼容性不好: 关于它的 polyfill 可以在 polyfill.io 或者 MDN上查看
updateState(event) {
const {name, value} = event.target;
let user = {...this.state.user, [name]: value};
this.setState({user});
}
更为简洁:
updateState({target}) {
this.setState({user: {...this.state.user, [target.name]: target.value}});
}
官方提供Immutability Helpers也可以实现
import update from 'immutability-helper';
updateState({target}) {
let user = update(this.state.user, {$merge: {[target.name]: target.value}});
this.setState({user});
}
注意:这个merge
方法只能提供浅复制
更多 immutability Helper 的用法参见 immutability-helper Github
import { Map } from 'immutable';
// Later, in constructor...
this.state = {
// Create an immutable map in state using immutable.js
user: Map({ firstName: 'Cory', lastName: 'House'})
};
updateState({target}) {
// this line returns a new user object assuming an immutable map is stored in state.
let user = this.state.user.set(target.name, target.value);
this.setState({user});
}
缺点在于 Immutable.js 体积过大,且语法不是很贴切。
原文链接