美文网首页程序员
React从零开始(4)——表单和列表

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

作者: 心扬 | 来源:发表于2017-12-20 22:24 被阅读0次

    表单是前端开发中必不可少的组件,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的学习中了!

    相关文章

      网友评论

        本文标题:React从零开始(4)——表单和列表

        本文链接:https://www.haomeiwen.com/subject/kndcixtx.html