yuadhのinterview_note yuadhのinterview_note
前端基础
软件框架
算法|数据结构
基础学科
系统|工具
项目
面试综合
专栏
GitHub (opens new window)
前端基础
软件框架
算法|数据结构
基础学科
系统|工具
项目
面试综合
专栏
GitHub (opens new window)
  • vscode

  • vue

  • react

    • heima

      • react快速开始
      • react受控和非受控组件
        • 受控组件
          • 使用步骤
          • 示例demo
          • 多表单元素优化
          • 步骤
          • 示例demo
        • 非受控组件
          • 使用步骤
        • 评论列表案例
          • 需求分析
          • 搭建评论列表的模板
          • 渲染评论列表
          • 渲染暂无评论
          • 获取评论信息
          • 发表评论
      • react组件通信
      • react生命周期
      • react路由
      • react的hooks
      • react生态redux
      • react生态router
    • react官方

  • 软件框架
  • react
  • heima
yuadh
2022-12-01
目录

react受控和非受控组件

# 受控组件

  • HTML中的表单元素是可输入的,也就是有自己的可变状态
  • 而React中可变状态通常保存在state中,并且只能通过setState() 方法来修改
  • React讲state与表单元素值value绑定在一起,有state的值来控制表单元素的值
  • 受控组件:值受到react控制的表单元素

# 使用步骤

  • 在state中添加一个状态,作为表单元素的value值
  • 给表单元素绑定change事件,将表单元素的值设置为state的值

# 示例demo

class App extends React.Component {
    constructor(){
        super()
        this.inputChange = this.inputChange.bind(this)
    }
    state = {
        txt : ''
    }
    inputChange(e){
       this.setState({
           txt: e.target.value
       })
    }
    render(){
        console.log(this.state);
        
        return (
            <div>
                {/* 把state的值设置给输入框的value,绑定change事件,这样用户在输入内容的时候调用相应函数,在函数里面把当前设置的值赋值给state,从而达到数据的统一 */}
                <input type="text" value={this.state.txt} onChange={this.inputChange}/>
            </div>
        )
    }
}
ReactDOM.render(<App />,document.getElementById('root'))
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

# 多表单元素优化

  • 问题:每个表单元素都有一个单独的事件处理函数,这样太繁琐
  • 优化:使用一个事件处理程序同时处理多个表单元素
# 步骤
  • 给表单元素添加name属性(用来区分是哪一个表单),名称与state相同(用来更新数据的)
  • 根据表单内容来获取对应值
  • 在change事件处理程序中通过 [name] 来修改对应的state
# 示例demo
inputChange(e){
   let target = e.target;
   let value = target.type == 'checkbox' ? target.checked : target.value;
   this.setState({
       [e.target.name]: value
   })
}
<input type="text" value={this.state.txt} name="txt" onChange={this.inputChange}/>
<input type="checkbox" value={this.state.isChecked} name="isChecked" onChange={this.inputChange}/>
1
2
3
4
5
6
7
8
9

# 非受控组件

  • 说明:借助于ref,使用元素DOM方式获取表单元素值
  • ref的作用:获取DOM或者组件

# 使用步骤

  • 调用 React.createRef() 方法创建ref对象
  • 将创建好的 ref 对象添加到文本框中
  • 通过ref对象获取到文本框的值
class App extends React.Component {
    constructor(){
        super()
        
        //创建 ref
        this.txtRef = React.createRef()
    }
    // 获取文本框的值
    getTxt =() => {
        console.log(this.txtRef.current.value)
    }
    render(){
        return (
          <div>
            <input type ="text" ref={this.txtRef} />
            <button onClick ={this.getTxt}>获取值</button>
          </div>
        )
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 评论列表案例

# 需求分析

  • 渲染评论列表(列表渲染)
  • 没有评论数据时渲染:暂无评论(条件渲染)
  • 获取评论信息,包括评论人和评论内容(受控组件)
  • 发表评论,更新评论列表(setState())

# 搭建评论列表的模板

  • 结构
import React from 'react'
import ReactDOM from 'react-dom'

/* 
  评论列表案例

  comments: [
    { id: 1, name: 'jack', content: '沙发!!!' },
    { id: 2, name: 'rose', content: '板凳~' },
    { id: 3, name: 'tom', content: '楼主好人' }
  ]
*/

import './index.css'

class App extends React.Component {
  render() {
    return (
      <div className="app">
        <div>
          <input className="user" type="text" placeholder="请输入评论人" />
          <br />
          <textarea
            className="content"
            cols="30"
            rows="10"
            placeholder="请输入评论内容"
          />
          <br />
          <button>发表评论</button>
        </div>

        <div className="no-comment">暂无评论,快去评论吧~</div>
        <ul>
          <li>
            <h3>评论人:jack</h3>
            <p>评论内容:沙发!!!</p>
          </li>
        </ul>
      </div>
    )
  }
}

// 渲染组件
ReactDOM.render(<App />, document.getElementById('root'))
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
  • 样式
.app {
  width: 300px;
  padding: 10px;
  border: 1px solid #999;
}

.user {
  width: 100%;
  box-sizing: border-box;
  margin-bottom: 10px;
}

.content {
  width: 100%;
  box-sizing: border-box;
  margin-bottom: 10px;
}

.no-comment {
  text-align: center;
  margin-top: 30px;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 渲染评论列表

  • 在state中初始化评论列表数据
  state = {
    comments: [
      { id: 1, name: 'jack', content: '沙发!!!' },
      { id: 2, name: 'rose', content: '板凳~' },
      { id: 3, name: 'tom', content: '楼主好人' }
    ]
  }
1
2
3
4
5
6
7
  • 使用数组的map方法遍历state中的列表数据
  • 给每一个被遍历的li元素添加key属性
  • 在render方法里的ul节点下嵌入表达式
{
  this.state.comments.map(item => {
    return (
       <li key={item.id}>
          <h3>{item.name}</h3>
          <p>{item.content}</p>
       </li>
    )
  })
}
1
2
3
4
5
6
7
8
9
10

# 渲染暂无评论

  • 判断列表数据的长度是否为0

  • 如果为0,则渲染暂无评论

  • 如果不为0,那么渲染列表数据

  • 在jsx中大量写逻辑会导致很臃肿,所以我们可以把条件渲染的逻辑抽取成一个函数

/**
 * 条件渲染,这里抽取出来了,这样在结构中不会很混乱
 */
renderList(){
  if (this.state.comments.length === 0) {
    return (<div className="no-comment">暂无评论,快去评论吧~</div>)
  } else {
    return (
      <ul> {
        this.state.comments.map(item => {
          return (
            <li key={item.id}>
              <h3>{item.name}</h3>
              <p>{item.content}</p>
            </li>
          )
        })
      }
      </ul>
    )
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  • 在render的return方法里面调用这个函数即可
render() {
  return (
    <div>
      ...
      {/* 通过条件渲染来判断是否显示暂无评论 */}
      {this.renderList()}
    </div>
  )
}
1
2
3
4
5
6
7
8
9

# 获取评论信息

  • 通过受控组件来获取内容
  • 初始化用户名和用户内容的state
userName: '',
userContent: ''
1
2
  • 在结构中,把表单元素的value与state进行绑定,还需要绑定name属性和onChange属性
<input className="user" type="text" placeholder="请输入评论人" value={this.state.userName} name="userName" onChange={this.handleForm}/>
<br />
<textarea
  className="content"
  cols="30"
  rows="10"
  placeholder="请输入评论内容"
  value={this.state.userContent}
  name="userContent"
  onChange={this.handleForm}
/>
1
2
3
4
5
6
7
8
9
10
11
  • 在handleFrom函数中利用setState来让数据保持一致
  handleForm = (e) => {
     this.setState({
       [e.target.name] : e.target.value
     })
  }
1
2
3
4
5

# 发表评论

  • 给按钮绑定事件
  • 在事件处理程序中,通过state获取评论信息
  • 将评论信息添加到state中,利用setState来更新页面
  • 添加评论前需要判断用户是否输入内容
  • 添加评论后,需要情况文本框用户输入的值
handleClick = (e) => {
  // 拿到用户输入的内容
  let {userName,userContent} = this.state
  if(userName.trim()==='' || userContent.trim() === ''){
      alert('请输入内容')
      return
  }
  // 利用数组拓展运算符来进行数据的拼接,把用户输入的存放在数组的第一个位置
  let newComments = [{
    id: this.state.comments.length+1,
    name: userName,
    content: userContent
  },...this.state.comments]
  this.setState({
    comments: newComments,
    userName:'',
    userContent: ''
  })
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
编辑 (opens new window)
上次更新: 2023/02/07, 15:11:55
react快速开始
react组件通信

← react快速开始 react组件通信→

最近更新
01
青训营真题day01
02-07
02
01day01-html与css
02-07
03
day02-js
02-07
更多文章>
Theme by Vdoing | Copyright © 2022-2023 yuadh | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式