React 框架-类组件

4/23/2024 react

# React 框架-类组件

  • 实现todolist 希望清单

# 1.JSX 实现 循环 渲染

jsx 没有任何的指令 v-for

jsx实现循环两种思路

思路2:通过 数组的 方法 进行循环遍历

userList = [
    {name:'xxx',age:22,avatar:'xxxxx'},
        {name:'xxx',age:22,avatar:'xxxxx'},
        {name:'xxx',age:22,avatar:'xxxxx'}
]

render(){
    return (
        {this.userList.map((item,index)=>{
           return <div key={index}>{item.name}</div>
    })}
    )
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# 2.JSX 实现 判断

jsx没有任何指令 v-if v-show

JSx 实现判断的思路

思路1: js表达式 三目运算符

this.userList[1].gender==1?'男':'女'
{user.gender==1?<div></div>:<div></div>}
1
2

思路2:js表达式 逻辑表达式

{
   user.age>20 && user.num==100 ? <div> 人名xxx</div>:null
}

{
   user.age>20 && user.num==100 && <div> 人名xxx</div>
}
1
2
3
4
5
6
7

思路3:借助 数组的 删选 查找 这些方法实现判断

{
    this.userList.filter(item=>item.num<60 && item.gender=='女').map(item=>{<div key={}> 人名xxx</div>})
}
1
2
3
math = 91;
  english = 90;

  userList = [
    { name: "张麻子", age: 22, gender: "0", num: 100, avatar: "xxxxx" },
    { name: "黄四郎", age: 22, gender: "0", num: 30, avatar: "xxxxx" },
    { name: "马邦德", age: 22, gender: "1", num: 70, avatar: "xxxxx" },
    { name: "师爷", age: 22, gender: "1", num: 45, avatar: "xxxxx" },
  ];

  // 1.输出列表中 性别是女 成绩==100
  render() {
    return (
      <>
        {this.math > 60 ? <div>及格</div> : <div>不及格</div>}

        {this.math >= 90 && this.english >= 90 && <h1>综合成绩优秀</h1>}

        {this.userList
          .filter((item) => item.num > 60)
          .map((item, index) => (
            <div key={index}> 满足条件的同学: {item.name} </div>
          ))}
      </>
    );
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import { Component } from "react";
export default class App extends Component {
    students = [
        {
            sno: '001',
            name: '小明',
            age: 22,
            like: '篮球、足球、乒乓球',
            num: 80
        },

        {
            sno: '003',
            name: '小源',
            age: 20,
            like: '篮球、乒乓球',
            num: 59
        },
        {
            sno: '002',
            name: '小红',
            age: 17,
            like: 'html、css',
            num: 70
        },
    ]

    render() {
        return (
            // 
            <>
                <table>
                    <thead>
                        <tr>
                            <th>学号</th>
                            <th>姓名</th>
                            <th>年龄</th>
                            <th>爱好</th>
                            <th>分数</th>
                        </tr>

                    </thead>
                </table>
                {/* 1.按学号排序
                {
                    this.students.sort((a, b) => {
                        return a.sno - b.sno;
                    }).map((item, index) => {
                        return (
                            <table key={index}>
                                <tbody >
                                    <tr>
                                        <td>{item.sno}</td>
                                        <td>{item.name}</td>
                                        <td>{item.age}</td>
                                        <td>{item.like}</td>
                                        <td>{item.num}</td>
                                    </tr>

                                </tbody>
                            </table>
                        )
                    })

                } */}

                {/* 2. 筛选出大于18岁的学生
                {
                    this.students.filter(item=>item.age>18).map((item,index)=>{
                        return (
                            <table key={index}>
                                <tbody >
                                    <tr>
                                        <td>{item.sno}</td>
                                        <td>{item.name}</td>
                                        <td>{item.age}</td>
                                        <td>{item.like}</td>
                                        <td>{item.num}</td>
                                    </tr>

                                </tbody>
                            </table>
                        )
                    })
                } */}

                {/* 3.是否有不及格的学生
                {
                    this.students.some((item)=>{
                        return item.num < 60
                    })?'存在':'不存在'
                } */}

                {/* 4.是否所有学生都满18岁
                {
                    this.students.every((item) => {
                        return item.age >18
                    }) ? 'yes' : 'no'
                } */}

                {/* 5.把所有学生的年龄 +1
                {
                    this.students.map((item,index)=>{
                        return (
                            <table key={index}>
                                <tbody >
                                    <tr>
                                        <td>{item.sno}</td>
                                        <td>{item.name}</td>
                                        <td>{item.age+1}</td>
                                        <td>{item.like}</td>
                                        <td>{item.num}</td>
                                    </tr>

                                </tbody>
                            </table>
                        )  
                    })
                } */}

                {/* 6.找出第一个分数大于等于80的学生 */}
                {
                    this.students.find((item,index)=>{
                        return item.num>=80
                    })?(
                        <table>
                            <tbody>
                                <tr>
                                    <td>{this.students.find((item) => item.num >= 80).sno}</td>
                                    <td>{this.students.find((item) => item.num >= 80).name}</td>
                                    <td>{this.students.find((item) => item.num >= 80).age}</td>
                                    <td>{this.students.find((item) => item.num >= 80).like}</td>
                                    <td>{this.students.find((item) => item.num >= 80).num}</td>
                                </tr>
                            </tbody>
                        </table>
                    ):'no'
                }
            </>
        )
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143

# 3.React 合成事件

基于 原生js事件 进行扩展, 合成事件对象 event

事件类型:

鼠标

点击click 双击dblclick 移入mouseover mouseenter 移出mouseleave mouseout

键盘

按下 keydown 抬起keyup 按着不放keypress

window

滚动 scroll 窗口宽高变化resize

input

获得焦点focus 失去焦点 blur 改变change 输入 input

事件的四要素

事件源 dom 事件执行函数 事件类型 对象对象event

  • 事件的绑定

事件执行函数 不能够直接写 js代码 ,立即执行代码(不需要等待 事件的触发)

执行函数 只是一个定义执行函数的语句:()=>需要干的事情

<div onClick={事件执行函数}> </div>
1
<div onClick={()=>需要执行的事情}> </div>
1
       <div className="box" onClick={()=>console.log('点你了')}>点我啊</div>
1
  • 事件执行函数封装

//执行函数
bandle(){
  console.log('点你了') 
}
render(){
       <div className="box" onClick={()=>this.bandle()}>点我啊</div>
}
1
2
3
4
5
6
7
8
import React, { Component } from "react";

export default class Incident extends Component {
  bandle(a,b) {
    console.log(a,b);
    console.log("点你了");
  }
  render() {
    return (
      <>
        <div className="box" onClick={() => this.bandle(1000,2000)}>
          点我啊
        </div>
      </>
    );
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  • 事件执行函数 默认参数 合成事件对象 event

包含原生js 事件对象 所有的 内容: 点击的 位置 target 事件源 dom

react 事件源 是虚拟dom vnode

  bandle(event) {
    console.log(event);  //包含 所有的原生dom有属性 同时包含虚拟dom信息
    console.log("点你了");
  }
  render() {
    return (
      <>
        <div className="box" onClick={(event) => this.bandle(event)}>
          点我啊
        </div>
      </>
    );
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
  • 不写箭头函数 直接调用 直接将 封装函数 函数体放过来

缺点: 不能接收自定义数据

 bandle(event) {
    console.log(event);  //包含 所有的原生dom有属性 同时包含虚拟dom信息
    console.log("点你了");
  }


<div className="box" onClick={this.bandel}>
          点我啊
        </div>
1
2
3
4
5
6
7
8
9
  • 小结

不需要传递参数 默认自带合成事件对象

<div  onClick={this.事件执行函数}> </div>
1

传递数据 借助箭头函数

<div  onClick={()=>this.事件执行函数(参数1,参数2)}> </div>
1

需要合成事件对象

<div  onClick={(event)=>this.事件执行函数(event,参数1,参数2)}> </div>
1

# 4.响应式数据

  • 定义响应式数据
class xxx extends Component{
    //state 定义状态:装当前页面 用到的所有的数据
    state = {
        num:1,
        user:{name:'xxxx'},
        arr:[]
    }
}
1
2
3
4
5
6
7
8
  • 使用响应式数据
this.state.num 
1
  • 修改响应式 数据
this.setState({
    num:this.state.num+1
})
//多个数据修改
this.setState({
    num:this.state.num+1,
    key2:'新数据',
   	key3:'新数据'
})
1
2
3
4
5
6
7
8
9
  • 案例
  // 定义状态
  state = {
    num: 1,
    name:'张麻子'
  };
//   递增
  add(){
    // 直接修改 state 中的状态值  数据会发生改变 ,但页面不会重新渲染
    // this.state.num++ 
    // console.log(this.state.num);
    // 借助 Component.prototype.setState(参数)  修改数据 且 让页面重新渲染 this   
    // 参数: 对 state属性 
    this.setState({
        num: this.state.num+1
    })

  }
  render() {
    return (
      <>
        <div>{this.state.num}</div>
        <div>{this.state.name}</div>
        <button onClick={()=>this.add()}> 递增</button>
      </>
    );
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 5.受控组件 与 非受控组件取值

受控组件: 可以通过 react 本身的 属性和事件 就可以获取数据

非受控组件:通过 获取dom的方式 再进行数据的获取

  • 受控组件
//1.定义状态
state = {
    account:'默认账号'
}

//箭头函数事件执行函数:根据input最新value 修改状态值
setAccount = (event)=>{
    this.setState({
        account:event.target.value
    })
}

//绑定事件 修改状态值   默认值: value绑定动态变量
<input   onChange={this.setAccount}   value={this.state.account}  / >
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  • 案例
   // 定义存数据的状态
    state = {
        name:'上善若水',
        tell:'132'
    }
    // 定义事件执行函数--获取数据 并赋值给state 
    // 写箭头函数的原因: this指向问题 
    setName = (event)=>{
        console.log(this);
        // 获取数据  event.target.value
        console.log(event.target.value);
        this.setState({
            name: event.target.value
        })
    }
    setTell = (event)=>{
        this.setState({
            tell: event.target.value
        })
    }
    
  render() {
    return (
      <div>
            <p>
                姓名: <input type="text" onChange={this.setName}  value={this.state.name} />
            </p>
            <p>
                手机号: <input type="text" onChange={this.setTell}  value={this.state.tell}/>
            </p>
            <button>提交</button>
            <h1> {this.state.name}</h1>
            <h1>{this.state.tell}</h1>
      </div>
    )
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

# 6.样式与类名操作

<div className="box"></div>
<div className={box}></div>
<div className={this.state.gender==1?box:box1}></div>
1
2
3
<div  style="width:300px;height:500px"></div>
<div style={{width:'300px',height:'500px',backgroundColor:this.state.color} }> </div>
1
2
  • 选项卡
// 定义状态:
  // 选中哪一个 标题 
   state = {
      active:0
   }
  //  修改当前选中的那个
  setActive = (current)=>{
    // 异步修改方法
    this.setState({
      active:current
    })
   
  }
  render() {
    return (
      <>
      <h1>{this.state.active}</h1>
        <div className="list">
          <div className="header">
            <div className={this.state.active==0?'title active':'title'}  onClick={()=>this.setActive(0)}>优选商品</div>
            <div className={this.state.active==1?'title active':'title'} onClick={()=>this.setActive(1)}>智能家居</div>
            <div className={this.state.active==2?'title active':'title'} onClick={()=>this.setActive(2)}>服装服饰</div>
          </div>
          <div className="content">
            {this.state.active ==0 && <div className="container">优选商品</div>  }
           {this.state.active ==1 &&  <div className="container">智能家居</div>}
           {this.state.active ==2 &&  <div className="container">服装服饰</div>}
          </div>
        </div>
      </>
    );
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

# 7.引用数据类型操作 注意事项

数据更改完成之后 必须通过 this.setState()修改 state中的状态值,才可以达到 数据响应式(数据改 ,页面自动修改)目的,

 state = {
        goodsList:[
            {
                id:1,
                name:'华为手机',
                price:4000,
            },
            {
                id:2,
                name:'小米手机',
                price:3800
            },
            {
                id:3,
                name:'苹果手机',
                price:5000
            }
        ]
    }

    // 下架商品
    del = (id)=>{
        let index =  this.state.goodsList.findIndex(item=>item.id==id)
        // 删除数组元素,先执行删除 通过setState 方法 赋值给 自己
        this.state.goodsList.splice(index,1)
        this.setState({
            goodsList: this.state.goodsList  
        })
    }

    addBtn = ()=>{
        let id = this.state.goodsList[this.state.goodsList.length-1].id
        let    goods= {
            id:id+1,
            name:'oppo手机',
            price:3000,
        }
        // push [最大索引]
        // this.state.goodsList[this.state.goodsList.length] = goods
        this.state.goodsList.push(goods)

        this.setState({
            goodsList:this.state.goodsList
        })
    }


  render() {
    return (
      <div>

            {
                this.state.goodsList.map(item=>(
                    <div className='item' key={item.id}>
                        <div className="name">商品名:{item.name}</div>
                        <div className="price">商品售价:{item.price}</div>
                        <div className="new-price">商品折扣价:{item.price*0.85}</div>
                        <button onClick={()=>this.del(item.id)}>下架</button>
                        <hr />
                    </div>
                 
                ))
            }
            <button onClick={this.addBtn}>添加商品</button>
      </div>
    )
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67