【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的思想,但是这两者的效率并没有太大的差异。



相关文章
|
27天前
|
前端开发 UED 索引
React 图片灯箱组件 Image Lightbox
图片灯箱组件是一种常见的Web交互模式,用户点击缩略图后弹出全屏窗口展示大图,并提供导航功能。本文介绍了基于React框架的图片灯箱组件开发,涵盖初始化状态管理、图片加载与预加载、键盘和鼠标事件处理等常见问题及解决方案。通过`useState`和`useEffect`钩子管理状态,使用懒加载和预加载优化性能,确保流畅的用户体验。代码案例展示了组件的基本功能实现,包括打开/关闭灯箱、切换图片及键盘操作。
127 80
|
11天前
|
移动开发 前端开发 JavaScript
React 视频播放控制组件 Video Controls
本文介绍了如何使用 React 构建视频播放控制组件(Video Controls),涵盖基本概念、创建步骤和常见问题解决。首先,通过 HTML5 `&lt;video&gt;` 标签和 React 组件化思想,实现播放/暂停按钮和进度条等基础功能。接着,详细讲解了初始化项目、构建 `VideoControls` 组件及与主应用的集成方法。最后,针对视频无法播放、控制器状态不同步、进度条卡顿和音量控制失效等问题提供了具体解决方案,并介绍了全屏播放和自定义样式等进阶功能。希望这些内容能帮助你在实际项目中更好地实现和优化视频播放功能。
83 40
|
26天前
|
移动开发 前端开发 JavaScript
React 视频播放器组件:Video Player
本文介绍了如何使用 React 和 HTML5 `&lt;video&gt;` 标签构建自定义视频播放器组件。首先,通过创建基础的 React 项目和 VideoPlayer 组件,实现了基本的播放、暂停功能。接着,探讨了常见问题如视频加载失败、控制条样式不一致、性能优化不足及状态管理混乱,并提供了相应的解决方案。最后,总结了构建高效视频播放器的关键要点,帮助开发者应对实际开发中的挑战。
110 27
|
29天前
|
前端开发 JavaScript API
React 图片放大组件 Image Zoom
本文介绍如何使用React创建图片放大组件(Image Zoom),提升用户体验。组件通过鼠标悬停或点击触发放大效果,利用`useState`管理状态,CSS实现视觉效果。常见问题包括图片失真、性能下降和移动端支持,分别可通过高质量图片源、优化事件处理和添加触摸事件解决。易错点涉及状态管理混乱、样式冲突和过多事件绑定,建议使用上下文API、CSS模块及优化事件绑定逻辑。高级功能扩展如多张图片支持和自定义放大区域进一步丰富了组件的实用性。
58 25
|
25天前
|
存储 编解码 前端开发
React 视频上传组件 Video Upload
随着互联网的发展,视频内容在网站和应用中愈发重要。本文探讨如何使用React构建高效、可靠的视频上传组件,涵盖基础概念、常见问题及解决方案。通过React的虚拟DOM和组件化开发模式,实现文件选择、进度显示、格式验证等功能,并解决跨域请求、并发上传等易错点。提供完整代码案例,确保用户能顺畅上传视频。
128 92
|
6天前
|
移动开发 前端开发 UED
React 音频预览组件:Audio Preview
本文介绍如何使用 React 构建音频预览组件,涵盖基础实现、常见问题及解决方案。通过 HTML5 `&lt;audio&gt;` 标签和 React 状态管理,实现播放控制。解决文件路径、浏览器兼容性等问题,并优化性能,避免状态不同步和内存泄漏,提升用户体验。
54 22
|
1天前
|
移动开发 前端开发 JavaScript
React 视频播放控制组件 Video Controls
本文深入探讨了如何使用React创建功能丰富的视频播放控制组件(Video Controls)。首先介绍了React与HTML5 `&lt;video&gt;` 标签的基础知识,展示了如何通过状态管理和事件处理实现自定义控件。接着分析了常见问题如视频加载失败、控件样式不一致、状态管理混乱和性能问题,并提供了相应的解决方案。最后通过完整代码案例详细解释了播放、暂停、进度条和音量控制的实现方法,帮助开发者在React中构建高质量的视频播放组件。
36 17
|
8天前
|
移动开发 前端开发 UED
React 音频播放器组件 Audio Player
本文介绍如何使用React创建功能丰富的音频播放器组件。基于HTML5 `&lt;audio&gt;` 标签,结合React的状态管理和事件处理,实现播放、暂停、进度和音量控制等功能。通过代码示例展示基本实现,并探讨常见问题如自动播放限制、进度条不更新、文件加载失败及多实例冲突的解决方案。同时,避免易错点如忽略生命周期管理、错误处理和性能优化,确保高效开发与良好用户体验。
62 23
|
10天前
|
缓存 前端开发 JavaScript
React 视频弹幕组件 Video Danmaku
本文介绍了如何在React中构建视频弹幕组件,提升用户观看体验和互动性。首先通过Create React App初始化项目,并集成`react-player`作为视频播放器。接着实现基本弹幕功能,包括评论的接收与显示,使用CSS动画实现滚动效果。针对常见问题如弹幕重叠、性能下降及同步问题,提供了随机化位置、分批加载和监听播放进度等解决方案。最后探讨了弹幕分类和特效等高级技巧,确保弹幕系统的高性能和良好用户体验。
52 23
|
28天前
|
存储 前端开发 索引
React 图片轮播组件 Image Carousel
本文介绍了如何使用React创建图片轮播组件。首先,解释了图片轮播的基本概念和组件结构,包括图片容器、导航按钮、指示器和自动播放功能。接着,通过代码示例详细说明了创建基本组件、添加自动播放、处理边界情况的步骤。还探讨了常见问题如状态更新不及时、内存泄漏和样式问题,并提供了解决方案。最后,介绍了进阶优化,如添加过渡效果、支持触摸事件和动态加载图片,帮助读者构建更完善的轮播组件。
52 16