React从零开始(4)——表单和列表

表单是前端开发中必不可少的组件,React作为前端框架,如果不能处理表单,就会被亿万的前端工程师吐槽的。然而React对于表单的处理,还是有一些细节上的东西需要关注,接下来我们详细的描述在React中如何使用表单组件。

为了让页面效果美观一点,在页面中引入bootstrap的css

npm install bootstrap --save

在react组件中引入外部css文件,直接可以使用import

import 'bootstrap/dist/css/bootstrap.css'

我们操作使用react,开发中最多的内容就是操作state中的数据,那么进行表单开发,就是要将表单中的数据与state中的数据关联起来,也就是说,当用户改变表单中的数据时,state中的数据也会相应的发生修改,当state中的数据发生了修改,form中的数据也会进行相应的变化。这种变化,以Angularjs的双向绑定最为著名,然而,react并没有使用双向绑定,而是使用了单向数据流。

单向数据流

在这里描述单向数据流,并不采用一些比较正规的说法,我所说的是在开发中的直观感受。在前端开发过程中,数据最终展示在页面中,需要经过一个渲染过程,即改变浏览器页面中的DOM结构或者DOM中的内容,从而浏览器进行了解析渲染,如果要开发人员手动写原生的JS代码操作DOM,在开发复杂应用时,那将是一个极其痛苦的过程。单向数据流的作用就是,当内存中的数据发生变化时,在页面的相应位置上,会自动的渲染这些数据,这就意味着开发人员不再写DOM操作的代码。

所谓单向数据流,意味着数据从一个地方流向另一个地方,即从浏览器内存页面DOM树

单向数据流

这就是react的强大之处,同时也是其短板之处,从内存到DOM,可以自动渲染,但是从DOM到内存,就需要开发人员手动处理。

创建表单

import React from 'react';
import 'bootstrap/dist/css/bootstrap.css'

class App extends React.Component{


    constructor(props){
        super(props);
        this.state = {
            name:''
        };
    }
    render(){
        return (
            <div className="container" style={{marginTop:'20px'}}>
                <div className="row">
                    <div className="col-md-5">
                        <form className="form-horizontal">
                            <div className="form-group">
                                <label className="col-sm-2 control-label">用户名</label>
                                <div className="col-sm-10">
                                    <input type="email" className="form-control" id="name" name="name" placeholder="用户名" />
                                </div>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        );
    }
}

export default App;

此时的表单中,其内部数据的状态由其自身维持,当用户在表单中进行输入时,表单的数据状态发生了变化,但是state中的状态仍然保持原状态,React只对表单组件进行了渲染,但并未控制其后续输入的变化,我们称此时的表单组件为非受控组件

让React渲染表单组件,组件中的值由React赋予,并控制其因用户输入所带来的变化,即让表单组件成为受控组件

  1. 表单组件的value值由React进行初始化
<input type="text" className="form-control" id="name" value={this.state.name} name="name" placeholder="用户名" onChange={this.handleChange}/>
  1. 监听组件change事件,将其变化的值修改保存到state中
handleChange = (event) =>{
    this.setState({
        [event.target.name]:event.target.value
    });
}

对于text,textarea,上述的方式均可,radio由于是单选,所以仍旧可以按照text的方式进行处理,但是对于checkbox,就需要做特殊的处理了

    <div className="form-group">
        <label className="col-sm-2 control-label">爱好</label>
        <div className="col-sm-10">
            <div className="checkbox">
                <label>
                    <input type="checkbox" name="hobby" value="1"/>音乐
                </label>
            </div>
            <div className="checkbox">
                <label>
                    <input type="checkbox" name="hobby" value="2"/>美术
                </label>
            </div>
            <div className="checkbox">
                <label>
                    <input type="checkbox" name="hobby" value="3"/>体操
                </label>
            </div>
        </div>
    </div>

checkbox组件为多选,所以,state中就需要使用数组来存储数据

  1. 使用onChange事件控制组件
  2. 修改state属性,要根据组件的checked属性来判断
    3.设置组件中的checked的值,需要根据state中的数据进行判断
  • 初始化state
    constructor(props){
        super(props);
        this.state = {
            music:false,
            draw:false,
            gymnastics:false
        };
    }
  • 为组件绑定onChange并对其checked进行判断
    <div className="form-group">
    <label className="col-sm-2 control-label">爱好</label>
    <div className="col-sm-10">
        <div className="checkbox">
            <label>
                <input type="checkbox" name="music" checked={this.state.music} onChange={this.handleChange}/>音乐
            </label>
        </div>
        <div className="checkbox">
            <label>
                <input type="checkbox" name="draw" checked={this.state.draw} onChange={this.handleChange}/>美术
            </label>
        </div>
        <div className="checkbox">
            <label>
                <input type="checkbox" name="gymnastics" checked={this.state.gymnastics} onChange={this.handleChange}/>体操
            </label>
        </div>
    </div>
</div>
  • 在onChange函数中进行数据处理
    handleChange = (event) =>{
        var temp = {
            [event.target.name]:event.target.checked
        };
        this.setState(temp);
    }

列表

现在业内流行的前端框架对于列表循环的支持,可以说是解放了广大 前端开发人员,从前的jquery疯狂拼接字符串,到后来使用一些插件,而现在,一切变得很简单
1.定义一组数组

const users = [{
    id:1,
    name:'张三',
    age:10
},{
    id:2,
    name:'李四',
    age:10
},{
    id:3,
    name:'王五',
    age:10
},{
    id:4,
    name:'赵六',
    age:10
}];

2.在render函数中首先根据数组生成列表组件

const tbodys = users.map((user)=>{
            return (
                <tr key={user.id}>
                    <td>{user.id}</td>
                    <td>{user.name}</td>
                    <td>{user.age}</td>
                </tr>
            )
   });

tbodys就是一个我们需要的列表组件,然后将其添加到render函数中返回的结构中

return (
            <div className="container" style={{marginTop:'30px'}}>
                <div className="row">
                    <div className="col-md-8 col-md-offset-2">
                        <table className="table table-bordered">
                            <thead>
                                <tr>
                                  <th>id</th>
                                  <th>名称</th>
                                  <th>年龄</th>
                                </tr>
                              </thead>
                              <tbody>
                                {tbodys}
                              </tbody>
                        </table>
                    </div>
                </div>

            </div>
        );

此时就得到一个完美的列表

列表

返回值得结构中的组件与前面使用map函数的遍历结构是等价的,因此,我们可以直接JSX中使用map函数遍历

render() {
        return (
            <div className="container" style={{marginTop:'30px'}}>
                <div className="row">
                    <div className="col-md-8 col-md-offset-2">
                        <table className="table table-bordered">
                            <thead>
                                <tr>
                                  <th>id</th>
                                  <th>名称</th>
                                  <th>年龄</th>
                                </tr>
                              </thead>
                              <tbody>
                                {

                                    users.map((user)=>{
                                        return (
                                            <tr key={user.id}>
                                                <td>{user.id}</td>
                                                <td>{user.name}</td>
                                                <td>{user.age}</td>
                                            </tr>
                                        )
                                    })
                                }
                              </tbody>
                        </table>
                    </div>
                </div>

            </div>
        );
    }

写到这里呢,React从零开始系 学习的系列就要结束了

之后我要重新回归java的学习中了!

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 原教程内容详见精益 React 学习指南,这只是我在学习过程中的一些阅读笔记,个人觉得该教程讲解深入浅出,比目前大...
    leonaxiong阅读 7,860评论 1 18
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 176,314评论 25 709
  • 原文地址:CSS clear both清除浮动 DIV+CSS clear both清除产生浮动我们知道有时使用了...
    LOOK_LOOK阅读 4,314评论 0 3
  • 今天已经完成任务但还没来的及发给他们看,谁知道手机竟然没信号,想在宿舍用WIFI发,不巧的是停电了。这些情况的罪魁...
    承思而行阅读 1,513评论 0 0
  • 第一次见到她的时候,她正咬牙切齿的呵斥一个男人,恶狠狠的短悍样子把我吓呆了,我不敢呼吸,懦懦的移走,生怕被殃及。 ...
    鱼丽枝阅读 2,622评论 0 0

友情链接更多精彩内容