一、react - 生命周期
简单来说 - react Component通过定了几个函数来控制各个阶段的动作。
1、 componentWillMount 组件挂载前(组件渲染前)
2、componentDidMount 组件挂载后(组件渲染后)
3、componentWillUpdate 组件更新前
4、componentDidUpdate 组件更新后
5、componentWillUnmount 组件卸载之前
(1)componentWillMount 组件挂载前(组件渲染前)
特点:
1.找不到元素
2.属性、状态允许使用
以下是实例:
<!doctype html> <html> <head> <meta charset="utf-8"> <title></title> <script type="text/javascript" src='bower_components/react/react.js'></script> <script type="text/javascript" src='bower_components/react/react-dom.js'></script> <script type="text/javascript" src='bower_components/babel/browser.js'></script> </head> <body> <div id='app'></div> <script type='text/babel'> class Leo extends React.Component{ constructor(){ super(); this.state={a:'state不是渲染内容,可以显示'} } componentWillMount(){ console.log(this.state.a) console.log(this.props.b) console.log("div1是渲染内容,所以在组件渲染前不能使用"+document.querySelector('#div1')) console.log('组件挂在前') } render(){ return ( <div id = 'div1'>hello</div> ) } } ReactDOM.render(<Leo b="props不是渲染内容,是属性,可以显示"/>,app);</script </body> </html> |
显示结果:
(2)componentDidMount 组件挂载后(组件渲染后)
特点:
1.可以找到元素
2.属性、状态允许使用
实例代码:
<script type='text/babel'> class Leo extends React.Component{ constructor(){ super(); this.state={a:'state不是渲染内容,可以显示'} } componentDidMount(){ console.log(this.state.a) console.log(this.props.b) console.log("div1是渲染内容,所以在组件渲染后能使用"+document.querySelector('#div1')) console.log('组件挂在前') } render(){ return ( <div id = 'div1'>hello</div> ) } } ReactDOM.render(<Leo b="props不是渲染内容,是属性,可以显示"/>,app); </script> |
结果:
(3)componentWillUpdate 组件更新前
特点:
1.可以找到元素
2.属性、状态允许使用
class Leo extends React.Component{ constructor(){ super(); this.state = { msg:'hello react!' } } componentWillUpdate(){ console.log('组件更新前'); debugger; } show(){ this.setState({ msg:Math.random() }) } render(){ return (<div> <input value="点击" onClick={this.show.bind(this)} type='button'/> <div id='div1'>{this.state.msg}</div> </div>) } } ReactDOM.render(<Leo l='1'/>,app); |
componentDidUpdate 组件更新后
特点:
1.可以找到元素
2.属性、状态允许使用
class Leo extends React.Component{ constructor(){ super(); this.state = { msg:'hello react!' } } componentWillUpdate(){ console.log('组件更新前'); //debugger; } componentDidUpdate(){ console.log('组件更新后'); } show(){ this.setState({ msg:Math.random() }) } render(){ return (<div> <input value="点击" onClick={this.show.bind(this)} type='button'/> <div id='div1'>{this.state.msg}</div> </div>) } } ReactDOM.render(<Leo l='1'/>,app); |
componentWillUnmount 组件卸载之前
<script type='text/babel'> class Leo extends React.Component{ constructor(){ super(); this.state = { msg:'hello react!' } } componentWillMount(){ //console.log(document.querySelector('#div1')) //console.log(this.props.l,this.state) console.log('组件挂载前'); } componentDidMount(){ //console.log(document.querySelector('#div1')) //console.log(this.props.l,this.state) console.log('组件挂载后'); } componentWillUpdate(){ console.log('组件更新前'); //debugger; } componentDidUpdate(){ console.log('组件更新后'); } show(e){ this.setState({ msg:Math.random() }); e.stopPropagation(); //e.cancelBubble = true; } componentWillUnmount(){ console.log('组件卸载之前') } render(){ return (<div> <input value="点击" onClick={this.show.bind(this)} type='button'/> <div id='div1'>{this.state.msg}</div> </div>) } } ReactDOM.render(<Leo l='1'/>,app); document.οnclick=function(){ //app.innerHTML = ''; ReactDOM.render(<h1>asdasd</h1>,app); } </script> |
显示结果
二、事件冒泡
时间冒泡实例:其中click的show事件和document.onclick产生了混淆,点击按钮本来只想出发show,却同时触发了document.onclick
<script type='text/babel'> class Leo extends React.Component{ constructor(){ super(); this.state = { msg:'hello react!' } } componentWillMount(){ //console.log(document.querySelector('#div1')) //console.log(this.props.l,this.state) console.log('组件挂载前'); } componentDidMount(){ //console.log(document.querySelector('#div1')) //console.log(this.props.l,this.state) console.log('组件挂载后'); } componentWillUpdate(){ console.log('组件更新前'); //debugger; } componentDidUpdate(){ console.log('组件更新后'); } show(e){ this.setState({ msg:Math.random() }); e.stopPropagation(); //e.cancelBubble = true; } componentWillUnmount(){ console.log('组件卸载之前') } render(){ return (<div> <input value="点击" onClick={this.show.bind(this)} type='button'/> <div id='div1'>{this.state.msg}</div> </div>) } } ReactDOM.render(<Leo l='1'/>,app);
document.οnclick=function(){ //app.innerHTML = ''; ReactDOM.render(<h1>asdasd</h1>,app); }
</script> |
结果:
原生的三个解决方法都不好使
1、return false;
2、e.stopPropagation();
3、e.cancelBubble = true;
e.nativeEvent.cancelBubble = true;
有效的解决方法
e -react封装过的nativeEvent 原生的事件对象
代码
show(e){ this.setState({ msg:Math.random() });
e.nativeEvent.stopImmediatePropagation(); //e.nativeEvent.cancelBubble = true; //console.log(e.nativeEvent) //return false; //e.stopPropagation(); //e.cancelBubble = true; } |
e.nativeEvent.stopImmediatePropagation()
停止立即的传播