state
state: 在写代码的时候要分析哪些数据是组件自身的
class Title extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>{ this.props.title }</div>
)
}
}
class DateTime extends React.Component {
constructor(props) {
super(props);
this.t = null;
}
state = {
dataTime: new Date().toString()
}
// 挂载到真实dom后执行
componentDidMount() {
this.t = setInterval(() => {
this.setState({
dataTime: new Date().toString()
})
}, 1000)
}
// 组件即将被卸载前
componentDidMount() {
// 清楚定时器
clearInterval(this.t);
this.t = null;//释放空间
}
render() {
return (
<h2 id="date-time">It's Now { this.state.dataTime }</h2>
)
}
}
class Board extends React.Component {
render() {
return (
<div>
<Title title="hello react"/>
<DateTime />
</div>
)
}
}
ReactDOM.render(
<Board />,
document.getElementById('app')
)
// 卸载组件
setTimeout(() => {
ReactDOM.unmountComponentAtNode(
document.getElementById('app')
);
}, 5000)
总结:
1.如果想使用组件的时候,传入数据 - props 组件配置
- 如果是组件内部使用的数据 - state 私有数据 (状态)
- state 使用的注意事项
- 必须使用setState 方法来更改state
- 多个setState 是会合并调用的
- props 和state更新数据要谨慎 → 尽量避免直接依赖他们(很有可能是在异步程序中更新的)
- 可能导致数据不对 → 如下操作
this.setState({
t: this.state.t + this.props.content//=> 避免这种操作
})
- 多个setState 是会合并调用的解决方法如下 → 回调函数的形式
- 有2个方法参数,第一个写逻辑, 第二个在处理完成后的回调
this.setState((state, props) => ({
//=> state 是上一个state
//=> props 是此次更新时被使用props
t: state.t + props.content
}))
setState简单的原理实现
let state = {num: 0}
let callbacks = []
callbacks.push([(state => ({num: state.num + 1}), () => {console.log(state)})])//6
callbacks.push([(state => ({num: state.num + 2}), () => {console.log(state)})])//6
callbacks.push([(state => ({num: state.num + 3}), () => {console.log(state)})])//6
let cb
let fns = []
while(v = callbacks.shift()) {
const [cb, fn] = v
state = cb(state)
fns.push(fn)
}
fns.forEach(fn => fns)
5.setState 操作合并的原理 → 是浅合并 Object.assign(this.state, num: this.state.num + 1)
- → 操作用扩展运算符(推荐)
let arr = [1,2,3]
/****/
this.setState({
arr: [...arr, 4]
})