1.基本使用

创建组件

  1. import React from 'react';
  2. class hello extends React.Component {
  3. render() {
  4. return (
  5. <div>
  6. 这是movie组件
  7. </div>
  8. );
  9. }
  10. }
  11. export default hello;

使用组件

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import './index.css';
  4. import * as serviceWorker from './serviceWorker';
  5. import Hello from "@/components/hello"
  6. ReactDOM.render(
  7. <Hello></Hello>,
  8. document.getElementById('root')
  9. );
  10. serviceWorker.unregister();

2.state

注意点:

  1. 我们不能够直接修改state 比如this.state.msg = “”这是错误,因为他不会触发页面刷新 所以我们应该通过this.setState方法来更新数据

  2. setState有可能是异步的,只要在react机制能够处理到的地方都是异步的,在react机制处理不到的地方都是同步的(比如setInterval setTimeout)

  3. 因为setState可能是异步的,所以我们想要setState之后立马获取最新的数据,我们可以使用setState的第二个参数(箭头函数)

  4. 因为setState可能是异步的,所以我们不能基于原来的state来修改当前的state,而是应该使用箭头函数作为setState的第一个参数

  5. 只要我们调用setState方法就会触发页面刷新,不管数据在页面有没有使用,也不管数据有没有发生变化,因为内部会调用batchingupdate方法来实现页面更新。对应的我们可以使用shouldComponetUpdate方法来做性能优化

  6. setState会把新的state合并到原来的state中

react中不能直接修改state,因此需要将之设置只读

  1. import React from 'react';
  2. const txtState={msg:"这里是组件自己特有的信息"}
  3. //获取 txtState类型
  4. type Istate=Readonly<typeof txtState>//设置为只读
  5. //这里的React.Component<p,s>,p这里的范型表示对props进行约定,s对state进行约定
  6. //将Istate作为它的类型给范型
  7. class movies extends React.Component<IProps,Istate> {
  8. //定义state的类型
  9. state:Istate=txtState
  10. render() {
  11. return (
  12. <div>
  13. {this.state.msg}
  14. </div>
  15. );
  16. }
  17. }
  18. export default movies;

修改state,使用setstate

  1. //定义类型,Readonly表示只读
  2. type IProps = Readonly<{
  3. name: string;
  4. age: number;
  5. }>;
  6. const txtState = { msg: "这里是组件自己特有的信息" ,count:1};
  7. //获取 txtState类型
  8. type Istate = typeof txtState;
  9. class movies extends React.Component<IProps, Istate> {
  10. //定义state的类型
  11. state: Istate = txtState;
  12. handleClick = () => {
  13. //这样来修改state中的数据
  14. this.setState({
  15. msg:"234"
  16. })
  17. };
  18. render() {
  19. return (
  20. <div>
  21. 数据是: {this.state.msg}
  22. <button onClick={this.handleClick}>修改数据</button>
  23. </div>
  24. );
  25. }
  26. }

state可能是异步的
image.png
我们在使用setState时无法基于原来的数值来推导当前的数值
image.png
如何在前一次修改了state的基础上对state进行修改?

  1. import React from "react";
  2. //定义类型,Readonly表示只读
  3. type IProps = Readonly<{
  4. name: string;
  5. age: number;
  6. }>;
  7. const txtState = { msg: "这里是组件自己特有的信息" ,count:1};
  8. //获取 txtState类型
  9. type Istate = typeof txtState;
  10. //这里的React.Component<p,s>,p这里的范型表示对props进行约定,s对state进行约定
  11. //将Istate作为它的类型给范型
  12. class movies extends React.Component<IProps, Istate> {
  13. //定义state的类型
  14. state: Istate = txtState;
  15. handleClick1=()=>{
  16. this.setState((state:Istate,props:IProps)=>{
  17. return{
  18. count:state.count+1
  19. }
  20. })
  21. //这里的state和props都是当前最新的state
  22. this.setState((state:Istate,props:IProps)=>{
  23. return{
  24. count:state.count+1
  25. }
  26. })
  27. }
  28. render() {
  29. return (
  30. <div>
  31. 当前数量是:{this.state.count}
  32. <button onClick={this.handleClick1}>增加数据</button>
  33. </div>
  34. );
  35. }
  36. }
  37. export default movies;

在修改state之后如何立刻如何获得最新数据,this.state第二个参数是一个回调函数,在这个回调函数中可以拿到最新的数据

  1. this.setState((state:Istate,props:IProps)=>{
  2. return{
  3. count:state.count+1
  4. }
  5. },()=>{
  6. //这里可以获取修改好的最新数据,不然这里的setstate是异步的无法得到最新的数据
  7. console.log(this.state.count,"xxxxxxxxxxx")
  8. })

setstate会把当前的值和原来的state进行合并得到一个新的值
只要调用setstate,就会触发页面的重新渲染,不管这个state在页面有没有使用过,也不管这个state有没有发生变化。
手动决定是否渲染页面,利用shouldComponentUpdate

  1. //需不需要更新页面,如果该方法返回false不会更新页面,如果返回结果是true会更新页面
  2. //nextState将要更新的值,做性能优化
  3. shouldComponentUpdate(nextProps:IProps,nextState:Istate){
  4. if(JSON.stringify(this.state)===JSON.stringify(nextState)){
  5. return false
  6. }
  7. else{
  8. return true
  9. }
  10. }

setState会触发batchingUpdate方法来触发页面更新
** setState的实现过程**
3941614716-5b13d6d716035_articlex.png

  1. import React from "react";
  2. //定义类型,Readonly表示只读
  3. type IProps = Readonly<{
  4. name: string;
  5. age: number;
  6. }>;
  7. const txtState = { msg: "这里是组件自己特有的信息" ,count:1};
  8. //获取 txtState类型
  9. type Istate = {msg:string,count:number,name?:string};
  10. //这里的React.Component<p,s>,p这里的范型表示对props进行约定,s对state进行约定
  11. //将Istate作为它的类型给范型
  12. class movies extends React.Component<IProps, Istate> {
  13. //定义state的类型
  14. state: Istate = txtState;
  15. handleClick = () => {
  16. //这样来修改state中的数据
  17. this.setState({
  18. msg:"234"
  19. })
  20. };
  21. handleClick1=()=>{
  22. //state可能是异步的
  23. this.setState((state:Istate,props:IProps)=>{
  24. return{
  25. count:state.count+1
  26. }
  27. },()=>{
  28. //这里可以获取修改好的最新数据,不然这里的setstate是异步的无法得到最新的数据
  29. console.log(this.state.count,"xxxxxxxxxxx")
  30. })
  31. }
  32. handleClick2=()=>{
  33. this.setState((state,props)=>{
  34. return{
  35. name:"叶枫"
  36. }
  37. },()=>{
  38. console.log(this.state)
  39. })
  40. }
  41. //这里的state和props都是当前最新的state
  42. // this.setState((state:Istate,props:IProps)=>{
  43. // return{
  44. // count:state.count+1
  45. // }
  46. // })
  47. //需不需要更新页面,如果该方法返回false不会更新页面,如果返回结果是true会更新页面
  48. //nextState将要更新的值,做性能优化
  49. shouldComponentUpdate(nextProps:IProps,nextState:Istate){
  50. if(JSON.stringify(this.state)===JSON.stringify(nextState)){
  51. return false
  52. }
  53. else{
  54. return true
  55. }
  56. }
  57. render() {
  58. console.log("render函数执行了")
  59. return (
  60. <div>
  61. {/* 无法直接在这里进行.拿到对应的属性 */}
  62. {/* {JSON.stringify(this.props)} */}
  63. {this.props.name}
  64. {this.props.age}
  65. {this.state.msg}
  66. <br></br>
  67. 当前数量是:{this.state.count}
  68. <button onClick={this.handleClick}>修改数据</button>
  69. <button onClick={this.handleClick1}>增加数据</button>
  70. <button onClick={this.handleClick2}>点我可修改姓名</button>
  71. </div>
  72. );
  73. }
  74. }
  75. export default movies;