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.state
return (
<div>
<h1 >这个数字是:{count}</h1>
<button onClick={this.force}>强制更新</button>
</div>
)
}
}
ReactDOM.render(<Son name="王苏" />, document.getElementById("app"))
</script>
</body>
</html>
</body>
</html>
作用:将props映射到state
static getDerivedStateFromProps(nextProps,prevState){
const {type}=nextProps;
if(type!=prevState.type){ // 当传入的type发生变化时,更新state
return {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.state
count+=1
this.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.state
return (
<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.state
const 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.state
return (
<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>