1.getDerivedStateFromProps
返回状态对**象或者null,**返回状态对象不以state为主,state所有时刻都取决于props,横跨挂载和更新.
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title></head><body><!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title></head><body><div id="app"></div><script src="../js/react.development.js"></script><script src="../js/react-dom.development.js"></script><script src="../js/babel.min.js"></script><script src="../js/prop-types.js"></script><script type="text/babel">class Son extends React.Component {constructor(props) {console.log("constructor-son")super(props)this.state = {count: 0}}//不改变数据状态,强制更新页面force = () => {this.forceUpdate()}//返回状态对象不以state为主,state所有时刻都取决于props,横跨挂载和更新static getDerivedStateFromProps(props,state) {console.log("getDerivedStateFormProps",props,state);return props}componentDidMount() {console.log("componentDidMount");}//组件是否允许被更改shouldComponentUpdate() {console.log(this)console.log("shouldComponentUpdate-son")return true}// //组件将要更新// componentWillUpdate() {// console.log("componentWillUpdate-son")// }//组件更新完毕componentDidUpdate() {console.log("componentDidUpdate-son")}render() {console.log("render-son")let { count } = this.statereturn (<div><h1 >这个数字是:{count}</h1><button onClick={this.force}>强制更新</button></div>)}}ReactDOM.render(<Son name="王苏" />, document.getElementById("app"))</script></body></html></body></html>
作用:将props映射到statestatic getDerivedStateFromProps(nextProps,prevState){const {type}=nextProps;if(type!=prevState.type){ // 当传入的type发生变化时,更新statereturn {type}}return null //否则,对state不进行处理}
2. getSnapshotBeforeUpdate
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title></head><body><!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title></head><body><div id="app"></div><script src="../js/react.development.js"></script><script src="../js/react-dom.development.js"></script><script src="../js/babel.min.js"></script><script src="../js/prop-types.js"></script><script type="text/babel">class Son extends React.Component {constructor(props) {console.log("constructor-son")super(props)this.state = {count: 0}}//不改变数据状态,强制更新页面force = () => {this.forceUpdate()}//增加add=()=>{let {count}=this.statecount+=1this.setState({count})}//返回状态对象不以state为主,state所有时刻都取决于props,横跨挂载和更新static getDerivedStateFromProps(props,state) {console.log("getDerivedStateFormProps",props,state);return props}componentDidMount() {console.log("componentDidMount");}//组件是否允许被更改shouldComponentUpdate() {console.log(this)console.log("shouldComponentUpdate-son")return true}getSnapshotBeforeUpdate(){console.log("getSnapshotBeforeUpdate");return "wangsu"}// //组件将要更新// componentWillUpdate() {// console.log("componentWillUpdate-son")// }//组件更新完毕componentDidUpdate(preProps,preState) {console.log("componentDidUpdate-son",preProps,preState)}render() {console.log("render-son")let { count } = this.statereturn (<div><h1 >这个数字是:{count}</h1><button onClick={this.force}>强制更新</button><button onClick={this.add}>加一</button></div>)}}ReactDOM.render(<Son name="王苏" />, document.getElementById("app"))</script></body></html></body></html>
案例
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title></head><body><!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title></head><body><!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title></head><style>.box {height: 150px;width: 200px;background-color: gold;overflow: auto;}.box div {height: 30px;}</style><body><div id="app"></div><script src="../js/react.development.js"></script><script src="../js/react-dom.development.js"></script><script src="../js/babel.min.js"></script><script src="../js/prop-types.js"></script><script type="text/babel">class News extends React.Component {state = {newsArr: []}componentDidMount() {setInterval(() => {const { newsArr } = this.stateconst news = `新闻${newsArr.length + 1}`this.setState({//将新增新闻传递到新数组中去newsArr: [news, ...newsArr]})}, 1000)}//这里可以得到上一次滚动的高度getSnapshotBeforeUpdate() {return this.box.scrollHeight}//现在的高度等于上一次的高度加上滚动高度的差值componentDidUpdate(prevProps, prevState, height) {//此时的this.box.scrollHeight是这一次滚动的高度this.box.scrollTop+=this.box.scrollHeight-height}render() {let { newsArr } = this.statereturn (<div className="box" ref={c => this.box = c}>{newsArr.map((n, index) =><div key={index}>{n}</div>)}</div>)}}ReactDOM.render(<News />, document.getElementById("app"))</script></body></html></body></html></body></html>
