下载包
react:核心库,包含生成虚拟dom的react.createElement函数以及继承的Component类
react-dom:核心功能是将虚拟dom渲染成实际的dom
babel-eslint:es6转es5,兼容不支持es6的浏览器,并且babel内嵌了对JSX的支持
2、setState执行机制
class Example extends React.Component {
constructor() {
super();
this.state = {
val: 0
};
}
componentDidMount() {
this.setState({val: this.state.val + 1});
console.log(this.state.val); // 第 1 次 log
this.setState({val: this.state.val + 1});
console.log(this.state.val); // 第 2 次 log
setTimeout(() => {
this.setState({val: this.state.val + 1});
console.log(this.state.val); // 第 3 次 log
this.setState({val: this.state.val + 1});
console.log(this.state.val); // 第 4 次 log
}, 0);
}
render() {
return null;
}
};
输出结果:0,0,2,3
在React的setState函数实现中,会根据一个变量 isBatchingUpdate 来判断是直接同步更新this.state还是放到队列中异步更新 。React使用了事务的机制,React的每个生命周期和合成事件都处在一个大的事务当中。在事务的前置钩子中调用batchedUpdates方法修改isBatchingUpdates变量为true,在后置钩子中将变量置为false。在此执行setState不会立即执行,会将修改状态放入队列中,将多次状态合成一次进行修改。在原生事件绑定和setTimeout异步的函数中,引发后置钩子触发,所以此时的setState会直接进入非批量更新模式,表现在我们看来成为了同步SetState。
1、ref
在react的自上而下的数据流中,父子组件交互是通过props实现的。state或者props改变,会导致子组件重新渲染。子组件调用父组件的方法,可以使用this.props.handle()。
实际中也会有父组件需要调用子组件方法的场景,这时就需要使用refs。两种方式使用:
PS:不能在函数组件上使用 ref 属性,因为他们没有实例
React.createRef()
( React 16.3 版本引入)
回调Refs
React.createRef()
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
}
componentDidMount(){
// 调用子组件的方法
this.myRef.current.focusTextInput();
}
render() {
return <ChildComponent ref={this.myRef} />;
}
}
回调Refs
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = el => {
this.textInput = el
};
}
render() {
return <ChildComponent ref={el => this.myRef = el} />;
}
}
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myRef = el => {
this.textInput = el
};
}
render() {
return <ChildComponent ref={this.myRef} />;
}
}
不能在函数组件上使用,因为没有实例。