image.png

1.getDerivedStateFromProps

返回状态对**象或者null,**返回状态对象不以state为主,state所有时刻都取决于props,横跨挂载和更新.

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>Document</title>
  8. </head>
  9. <body>
  10. <!DOCTYPE html>
  11. <html lang="en">
  12. <head>
  13. <meta charset="UTF-8">
  14. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  15. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  16. <title>Document</title>
  17. </head>
  18. <body>
  19. <div id="app"></div>
  20. <script src="../js/react.development.js"></script>
  21. <script src="../js/react-dom.development.js"></script>
  22. <script src="../js/babel.min.js"></script>
  23. <script src="../js/prop-types.js"></script>
  24. <script type="text/babel">
  25. class Son extends React.Component {
  26. constructor(props) {
  27. console.log("constructor-son")
  28. super(props)
  29. this.state = {
  30. count: 0
  31. }
  32. }
  33. //不改变数据状态,强制更新页面
  34. force = () => {
  35. this.forceUpdate()
  36. }
  37. //返回状态对象不以state为主,state所有时刻都取决于props,横跨挂载和更新
  38. static getDerivedStateFromProps(props,state) {
  39. console.log("getDerivedStateFormProps",props,state);
  40. return props
  41. }
  42. componentDidMount() {
  43. console.log("componentDidMount");
  44. }
  45. //组件是否允许被更改
  46. shouldComponentUpdate() {
  47. console.log(this)
  48. console.log("shouldComponentUpdate-son")
  49. return true
  50. }
  51. // //组件将要更新
  52. // componentWillUpdate() {
  53. // console.log("componentWillUpdate-son")
  54. // }
  55. //组件更新完毕
  56. componentDidUpdate() {
  57. console.log("componentDidUpdate-son")
  58. }
  59. render() {
  60. console.log("render-son")
  61. let { count } = this.state
  62. return (
  63. <div>
  64. <h1 >这个数字是:{count}</h1>
  65. <button onClick={this.force}>强制更新</button>
  66. </div>
  67. )
  68. }
  69. }
  70. ReactDOM.render(<Son name="王苏" />, document.getElementById("app"))
  71. </script>
  72. </body>
  73. </html>
  74. </body>
  75. </html>
  1. 作用:将props映射到state
  2. static getDerivedStateFromProps(nextProps,prevState){
  3. const {type}=nextProps;
  4. if(type!=prevState.type){ // 当传入的type发生变化时,更新state
  5. return {type}
  6. }
  7. return null //否则,对state不进行处理
  8. }

2. getSnapshotBeforeUpdate

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>Document</title>
  8. </head>
  9. <body>
  10. <!DOCTYPE html>
  11. <html lang="en">
  12. <head>
  13. <meta charset="UTF-8">
  14. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  15. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  16. <title>Document</title>
  17. </head>
  18. <body>
  19. <div id="app"></div>
  20. <script src="../js/react.development.js"></script>
  21. <script src="../js/react-dom.development.js"></script>
  22. <script src="../js/babel.min.js"></script>
  23. <script src="../js/prop-types.js"></script>
  24. <script type="text/babel">
  25. class Son extends React.Component {
  26. constructor(props) {
  27. console.log("constructor-son")
  28. super(props)
  29. this.state = {
  30. count: 0
  31. }
  32. }
  33. //不改变数据状态,强制更新页面
  34. force = () => {
  35. this.forceUpdate()
  36. }
  37. //增加
  38. add=()=>{
  39. let {count}=this.state
  40. count+=1
  41. this.setState({
  42. count
  43. })
  44. }
  45. //返回状态对象不以state为主,state所有时刻都取决于props,横跨挂载和更新
  46. static getDerivedStateFromProps(props,state) {
  47. console.log("getDerivedStateFormProps",props,state);
  48. return props
  49. }
  50. componentDidMount() {
  51. console.log("componentDidMount");
  52. }
  53. //组件是否允许被更改
  54. shouldComponentUpdate() {
  55. console.log(this)
  56. console.log("shouldComponentUpdate-son")
  57. return true
  58. }
  59. getSnapshotBeforeUpdate(){
  60. console.log("getSnapshotBeforeUpdate");
  61. return "wangsu"
  62. }
  63. // //组件将要更新
  64. // componentWillUpdate() {
  65. // console.log("componentWillUpdate-son")
  66. // }
  67. //组件更新完毕
  68. componentDidUpdate(preProps,preState) {
  69. console.log("componentDidUpdate-son",preProps,preState)
  70. }
  71. render() {
  72. console.log("render-son")
  73. let { count } = this.state
  74. return (
  75. <div>
  76. <h1 >这个数字是:{count}</h1>
  77. <button onClick={this.force}>强制更新</button>
  78. <button onClick={this.add}>加一</button>
  79. </div>
  80. )
  81. }
  82. }
  83. ReactDOM.render(<Son name="王苏" />, document.getElementById("app"))
  84. </script>
  85. </body>
  86. </html>
  87. </body>
  88. </html>

案例

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>Document</title>
  8. </head>
  9. <body>
  10. <!DOCTYPE html>
  11. <html lang="en">
  12. <head>
  13. <meta charset="UTF-8">
  14. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  15. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  16. <title>Document</title>
  17. </head>
  18. <body>
  19. <!DOCTYPE html>
  20. <html lang="en">
  21. <head>
  22. <meta charset="UTF-8">
  23. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  24. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  25. <title>Document</title>
  26. </head>
  27. <style>
  28. .box {
  29. height: 150px;
  30. width: 200px;
  31. background-color: gold;
  32. overflow: auto;
  33. }
  34. .box div {
  35. height: 30px;
  36. }
  37. </style>
  38. <body>
  39. <div id="app">
  40. </div>
  41. <script src="../js/react.development.js"></script>
  42. <script src="../js/react-dom.development.js"></script>
  43. <script src="../js/babel.min.js"></script>
  44. <script src="../js/prop-types.js"></script>
  45. <script type="text/babel">
  46. class News extends React.Component {
  47. state = {
  48. newsArr: []
  49. }
  50. componentDidMount() {
  51. setInterval(() => {
  52. const { newsArr } = this.state
  53. const news = `新闻${newsArr.length + 1}`
  54. this.setState({
  55. //将新增新闻传递到新数组中去
  56. newsArr: [news, ...newsArr]
  57. })
  58. }, 1000)
  59. }
  60. //这里可以得到上一次滚动的高度
  61. getSnapshotBeforeUpdate() {
  62. return this.box.scrollHeight
  63. }
  64. //现在的高度等于上一次的高度加上滚动高度的差值
  65. componentDidUpdate(prevProps, prevState, height) {
  66. //此时的this.box.scrollHeight是这一次滚动的高度
  67. this.box.scrollTop+=this.box.scrollHeight-height
  68. }
  69. render() {
  70. let { newsArr } = this.state
  71. return (
  72. <div className="box" ref={c => this.box = c}>
  73. {
  74. newsArr.map((n, index) =>
  75. <div key={index}>{n}</div>
  76. )
  77. }
  78. </div>
  79. )
  80. }
  81. }
  82. ReactDOM.render(<News />, document.getElementById("app"))
  83. </script>
  84. </body>
  85. </html>
  86. </body>
  87. </html>
  88. </body>
  89. </html>