【React】归纳篇(五)组件组合的使用 | 受控与非受控组件 | 组件的综合练习 | 获取表单数据

简介: 【React】归纳篇(五)组件组合的使用 | 受控与非受控组件 | 组件的综合练习 | 获取表单数据


今天我们来一个小练习,最常见的TODO练习,将组件进行组合使用。

首先明确以下3点:

功能界面的组件化编码流程(重要)

  • 1、拆分组件:例如把一个整体界面进行拆分,分为一个个单个组件
  • 2、实现静态组件:使用组件实现静态页面效果
  • 3、实现动态苏建:动态显示初始化数据;实现交互功能,如绑定事件监听

思考?

  • 数据应该保存在哪个组件内?

分析:

  • 1、看数据是某个组件需要,还是某些组件需要。某个组件需要就保存在某个组件。某些组件需要就保存在这些组件共同的父组件中;
  • 2、然后看数据是什么类型;

思考?

  • 子组件中改变父组件的状态:不能在子组件中直接改变父组件的状态
  • 方法:状态在哪个组件,更新状态的行为(函数)就应该定义在哪个组件
  • 子组件去调用父组件的方法
  • 父组件定义函数,传递给子组件,子组件进行调用

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div id="test1"></div>
    <div id="test2"></div>
    <script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
    <script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
    <script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
    <script src="../js/prop-types.js"></script>
    <script type="text/babel">
       //Todo List
       //1、定义组件:将整体组件拆分为3个单个组件
       //将<Add />与<List />组件放在<App />组件中,实现一个静态组件
       //2、动态显示初始化数据——数据应该保存在哪个组件内
       //3、添加交互,监听事件绑定
       class App extends React.Component {
           constructor(props){
               super(props)
               //初始化状态设置
               this.state = {
                   todos: ['aaa','bbb','ccc']
               }
               this.addTodo = this.addTodo.bind(this);  
           }
           addTodo(todo) {
                const {todos} = this.state;
                todos.unshift(todo);
                //更新状态
                this.setState({todos});
           }
           render() {
               const {todos} = this.state;//解构赋值写法
               return (
                <div>
                    <h1>TODO LIST</h1>
                    <Add count={todos.length} addTodo={this.addTodo}/>  
                    <List todos={todos}/>
                </div>
               )
           }
       }
       class Add extends React.Component {
           constructor(props){
               super(props)
               this.handleAdd = this.handleAdd.bind(this);
           }
           handleAdd() {
                //1、读取输入的数据
                const todo = this.inputVal.value.trim()
                //2、检测合法性,合法则添加
                if(!todo){
                    return 
                }
                this.props.addTodo(todo);//因为addTodo被放在属性中传过来
                this.inputVal.value='';
           }
           render() {
               return (
                   <div>
                    <input type="text" ref={input => this.inputVal=input}/>
                    <button onClick={this.handleAdd}>增加 {this.props.count+1}</button>
                   </div>
               )
           }
       }
       Add.propTypes = {
           count: PropTypes.number.isRequired,
           addTodo:PropTypes.func.isRequired
       }
       class List extends React.Component {
           render() {
               return (
                   <ul>
                    {
                        this.props.todos.map((todo,index)=>{return <li key={index}>{todo}</li>})
                    }
                   </ul>
               )
           }
       }
       List.propTypes = {
           todos: PropTypes.array.isRequired
       }
       ReactDOM.render(<App />,document.getElementById('test1'));
    </script>
</body>
</html>

小结–组件组合编写的流程(记住流程)

  • 1、拆分组件:根据页面结构拆分组件
  • 2、实现静态组件:先给组件类指定render(),每个组件都指定。(此时没有动态数据与交互)
  • 3、实现动态组件:先初始化数据的动态显示;然后再添加交互,绑定(bind)事件监听。

在组件中收集表单数据

实际工作中,我们常常需要操作表单数据,如向服务端提交表单数据要发送请求,如检验表单数据合法性,等等。。那么这些操作之前,首先我们需要收集到表单数据。

实例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div id="test1"></div>
    <script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
    <script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
    <script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
    <script src="../js/prop-types.js"></script>
    <script type="text/babel">
    //1、定义类组件
      class LoginForm extends React.Component {
          constructor(props) {
              super(props);
              //初始化状态
              this.state = {
                  psw : ''
              }
              this.handleSubmit = this.handleSubmit.bind(this);//绑定事件侦听
              this.handleChange = this.handleChange.bind(this);//绑定事件侦听
          }
          handleSubmit(event) {
            const name = this.nameInput.value;
            const {psw} = this.state;
            alert('username:'+name+' password:'+psw);
            //阻止事件的默认行为
            event.preventDefault();
          }
          //psw失去焦点事件
          handleChange(event) {
            //读取输入值
            const psw = event.target.value;
            //更新psw状态
            this.setState({psw});
          }
          render() {
              return (
                <form action="" method="" onSubmit={this.handleSubmit}>
                    <label htmlFor="username">用户名:</label>
                    <input type="text" id="username" ref={input => this.nameInput = input}/>
                    <label htmlFor="psw">密码:</label>
                    <input type="password" id="psw" value={this.state.psw} onChange={this.handleChange}/>
                    <input type="submit" value="Login In"/>
                </form>
              )
          }
      }
    //2、渲染组件
    ReactDOM.render(<LoginForm/>,document.getElementById('test1'));
    </script>
</body>
</html>

小结

包含表单的组件分为2类:

  • 受控组件:表单项输入数据能自动收集成状态state,如password,读状态state
  • 非受控组件: 需要时才手动读取表单的数据,如username,需要手动设置

“受控”与“非受控”两个概念,区别在于这个组件的状态是否可以被外部修改。一个设计得当的组件应该同时支持“受控”与“非受控”两种形式,即当开发者不控制组件属性时,组件自己管理状态,而当开发者控制组件属性时,组件该由属性控制。而开发一个复杂组件更需要注意这点,以避免只有部分属性受控,使其变成一个半受控组件。

大多数情况请,推荐使用“受控组件”来实现表单,比较符合React的思想,但是这两者的效率并没有太大的差异。



相关实践学习
Serverless极速搭建Hexo博客
本场景介绍如何使用阿里云函数计算服务命令行工具快速搭建一个Hexo博客。
相关文章
|
10天前
|
前端开发 JavaScript 测试技术
React 分页组件 Pagination
本文介绍了如何在 React 中从零构建分页组件,涵盖基础概念、常见问题及解决方案。通过示例代码详细讲解了分页按钮的创建、分页按钮过多、初始加载慢、状态管理混乱等常见问题的解决方法,以及如何避免边界条件、性能优化和用户反馈等方面的易错点。旨在帮助开发者更好地理解和掌握 React 分页组件的开发技巧,提升应用的性能和用户体验。
36 0
|
11天前
|
前端开发 UED 开发者
React 数据表格分页实现
本文详细介绍了如何在React中实现数据表格的分页功能,包括基础实现、常见问题及解决方案。通过状态管理和事件处理,我们可以有效地减少页面加载时间,提升用户体验。文章提供了完整的代码示例,帮助开发者解决分页按钮样式、按钮过多和初始加载慢等问题,并给出了相应的优化方案。
90 53
|
1月前
|
前端开发 JavaScript 数据安全/隐私保护
深入探索研究React表单
【10月更文挑战第6天】
89 57
|
14天前
|
移动开发 前端开发 API
React 拖拽组件 Drag & Drop
本文介绍了在 React 中实现拖拽功能的方法,包括使用原生 HTML5 Drag and Drop API 和第三方库 `react-dnd`。通过代码示例详细讲解了基本的拖拽实现、常见问题及易错点,帮助开发者更好地理解和应用拖拽功能。
47 9
|
9天前
|
前端开发 UED 开发者
React 分页组件 Pagination
本文介绍了如何在 React 中实现分页组件,从基础概念到常见问题及解决方案。分页组件用于将大量数据分成多个页面,提升用户体验。文章详细讲解了分页组件的基本结构、快速入门步骤、以及如何处理页面跳转不平滑、页码过多导致布局混乱、边界条件处理和数据加载延迟等问题。通过本文,读者可以全面了解并掌握 React 分页组件的开发技巧。
13 2
|
13天前
|
设计模式 前端开发 编译器
与普通组件相比,React 泛型组件有哪些优势?
与普通组件相比,React 泛型组件有哪些优势?
30 6
|
12天前
|
前端开发 搜索推荐 测试技术
React 数据表格排序与过滤
本文介绍了如何在 React 中实现数据表格的排序和过滤功能,从基础概念到实际代码实现,涵盖排序和过滤的基本原理、实现步骤、常见问题及解决方法。通过合理管理状态、优化性能和避免常见错误,帮助开发者提高用户体验和开发效率。
30 4
|
20天前
|
前端开发 JavaScript
React 表单处理技巧
【10月更文挑战第24天】本文从初学者角度出发,详细介绍了 React 中表单处理的基本概念、常见问题及解决方案。涵盖受控组件与非受控组件的区别、状态更新、表单验证、多字段管理及高级技巧,通过代码示例帮助读者更好地理解和应用。
51 7
|
21天前
|
前端开发 JavaScript 安全
学习如何为 React 组件编写测试:
学习如何为 React 组件编写测试:
35 2
|
28天前
|
前端开发 JavaScript 测试技术
React 高阶组件 (HOC) 应用
【10月更文挑战第16天】高阶组件(HOC)是 React 中一种复用组件逻辑的方式,通过接受一个组件并返回新组件来实现。本文介绍了 HOC 的基础概念、核心功能和常见问题,包括静态方法丢失、ref 丢失、多个 HOC 组合和 props 冲突的解决方案,并提供了具体的 React 代码示例。通过本文,读者可以更好地理解和应用 HOC,提高代码的复用性和可维护性。
58 8