• 学习React不是一蹴而就的事情,入门似乎也没那么简单。但一切都是值得的。今天给大家带来一个详细的React的实例,实例并不难,但对于初学者而言,足够认清React的思考和编写过程。认真完成这个实例的每一个细节会让...

    学习React不是一蹴而就的事情,入门似乎也没那么简单。但一切都是值得的。

    今天给大家带来一个详细的React的实例,实例并不难,但对于初学者而言,足够认清React的思考和编写过程。认真完成这个实例的每一个细节会让你受益匪浅。接下来我们开始吧!

    代码下载

    预览

    首先说明一下,本例究竟做了什么。本文实现了一个单页面人员管理系统的前台应用。包括以下功能:

    • 人员基本信息列表;
    • 人员的录入及删除;
    • 人员详细信息的查看;
    • 人员信息的编辑;
    • 根据人员身份进行筛选;
    • 根据人员某些属性进行排序;
    • 根据人姓名、年龄、身份、性别等关键字进行人员搜索。

    页面预览如下:

    图1

    图2

    为了更好地学习,请先到这里去感受一下:

    人员管理系统

    代码下载

    本文构建React组件的时候,使用了es6的语法,最终用webpack打包。最好有相关基础,我会在相关的地方进行言简意赅的说明。

    第一步:划分UI Component

    React is all about modular, composable components.

    React是模块化、组件化的。我们这里第一步要做的就是将应用划分成各个组件。我在图一、图二的基础上圈出了我们即将实现的各个组件。结果如图三、图四所示:

    图3

    图4

    每个圈出的组件功能如下,这是本应用的框架,请大家务必看清楚,其中斜体字是各个组件的名称:

    • ManageSystem 图三最外层的红色方框,这是管理模块的最外层容器,容纳整个应用;
    • StaffHeader 图三最上层蓝色方框,该模块接收用户操作的输入,包括关键字搜索输入、筛选条件以及排序方式;
    • StaffItemPanel 图三中间蓝色方框,该模块用于展示所有基于用户操作(关键字搜索、筛选、排序)结果的条目;
    • StaffFooter 图三最下层蓝色方框,该模块用于新人员的添加;
    • StaffItem 图三内层的红色方框,该模块用于展示一条人员的基本信息,包括删除和详情操作的按钮;
    • StaffDetail 图四的红色方框,每当点击StaffItem的’详情’后会显示该条目的详细信息。该模块用于展示人员的详细信息,兼有人员信息编辑的功能。

    为了更清楚地展示框架结构:

    ManageSystem
    
        StaffHeader
    
        StaffItemPanel
    
            StaffItem
            StaffItem
            StaffItem...
    
        StaffFooter
    
        StaffDetail(只在点击某条目的详情后展示)
    

    第二步:构建静态版的React应用

    在第一步中我们已经划分了各个组件,也说明了各个组件的职责。接下来我们分步完成我们的应用,首先我们做一个静态版的React,只用于render UI组件,但并不包含任何交互。

    这个步骤我们只需要参照图一、图二去做就好了,绝大部分工作基本上就是使用JSX按部就班地写html代码。这个过程不需要太多思考。每个组件中都仅仅只包含一个render()方法。

    需要注意的是,静态版的应用,数据由父组件通过props属性向下传递,state属性是用不到的,记住,state仅仅为动态交互而生。

    本应用的组件相对较多,我们不妨采用bottom-up的方式,从子组件开始。

    好了,我们开始吧。

    StaffHeader

    首先以StaffHeader为例,创建一个StaffHeader.js文件。如下:

    
    import React from 'react';
    export default class StaffHeader extends React.Component{
    
        render(){
            return (
              <div>
                  <h3 style={{'text-align':'center'}}>人员管理系统</h3>
                  <table className="optHeader">
                    <tbody>
                      <tr>
                        <td className="headerTd"><input type='text' placeholder='Search...' /></td>
                        <td className="headerTd">
                            <label for='idSelect'>人员筛选</label>
                            <select id='idSelect'>
                                <option value='0'>全部</option>
                                <option value='1'>主任</option>
                                <option value='2'>老师</option>
                                <option value='3'>学生</option>
                                <option value='4'>实习</option>
                            </select>
                        </td>
                        <td>
                            <label for='orderSelect'>排列方式</label>
                            <select id='orderSelect'>
                                <option value='0'>身份</option>
                                <option value='1'>年龄升</option>
                                <option value='2'>年龄降</option>
                            </select>
                        </td>
                      </tr>
                    </tbody>
                  </table>
              </div>
            );
        }
    }

    该组件主要用于提供搜索框,人员筛选下拉框以及排列方式下拉框。没错,我们首先就是要搭建一个静态版的React。呈现的样子参考图三最上方的蓝色框。当然,为了实现最终的样式,需要css的配合,css不是本文的关注点,本应用的css也十分简单,自行查看源代码。

    StaffItem

    StaffItem是每个具体人员的基本信息组件,用于展示人员的基本信息并接收用户的删除和点击详情的操作。新建一个StaffItem.js(该组件在StaffItemPanel中被引用):

    
    import React from 'react';
    export default class StaffItem extends React.Component{
    
        render(){
            return (
                  <tr
                    style={{'cursor': 'pointer'}}
                  >
                    <td className='itemTd'>{this.props.item.info.name}</td>
                    <td className='itemTd'>{this.props.item.info.age}</td>
                    <td className='itemTd'>{this.props.item.info.id}</td>
                    <td className='itemTd'>{this.props.item.info.sex}</td>
                    <td className='itemTd'>
                        <a className="itemBtn">删除</a>
                        <a className="itemBtn">详情</a>
                    </td>
                  </tr>
            );
        }
    }

    StaffItemPanel

    接下来是StaffItemPanel,该组件仅用于展示由父组件传入的各个人员条目,新建一个StaffItemPanel.js文件:

    
    import React from 'react';
    import StaffItem from './StaffItem.js';
    export default class StaffItemPanel extends React.Component{
    
        render(){
            let items = [];
    
            if(this.props.items.length == 0) {
                items.push(<tr><th colSpan="5" className="tempEmpty">暂无用户</th></tr>);
            }else {
                this.props.items.forEach(item => {
                    items.push(<StaffItem key={item.key} item={item}/>);
                });
            }
    
            return (
              <table className='itemPanel'>
                <thead>
                    <th className='itemTd'>姓名</th>
                    <th className='itemTd'>年龄</th>
                    <th className='itemTd'>身份</th>
                    <th className='itemTd'>性别</th>
                    <th className='itemTd'>操作</th>
                </thead>
                <tbody>{items}</tbody>
              </table>
            );
        }
    }

    该组件的功能相对简单,其中

    
            if(this.props.items.length == 0) {
                items.push(<tr><th colSpan="5" className="tempEmpty">暂无用户</th></tr>);
            }else {
                this.props.items.forEach(item => {
                    items.push(<StaffItem key={item.key} item={item} />);
                });
            }

    是为了在暂无条目的时候给出相应的提示,如下图:

    图5

    StaffFooter

    StaffFooter组件的功能是添加新人员,新建StaffFooter.js文件:

    
    import React from 'react';
    export default class StaffFooter extends React.Component{
    
        render(){
            return (
              <div>
                <h4 style={{'text-align':'center'}}>人员新增</h4>
                <hr/>
                <form ref='addForm' className="addForm">
                    <div>
                      <label for='staffAddName' style={{'display': 'block'}}>姓名</label>
                      <input ref='addName' id='staffAddName' type='text' placeholder='Your Name'/>
                    </div>
                    <div>
                      <label for='staffAddAge' style={{'display': 'block'}}>年龄</label>
                      <input ref='addAge' id='staffAddAge' type='text' placeholder='Your Age(0-150)'/>
                    </div>
                    <div>
                      <label for='staffAddSex' style={{'display': 'block'}}>性别</label>
                      <select ref='addSex' id='staffAddSex'>
                        <option value='男'></option>
                        <option value='女'></option>
                      </select>
                    </div>
                    <div>
                      <label for='staffAddId' style={{'display': 'block'}}>身份</label>
                      <select ref='addId' id='staffAddId'>
                        <option value='主任'>主任</option>
                        <option value='老师'>老师</option>
                        <option value='学生'>学生</option>
                        <option value='实习'>实习</option>
                      </select>
                    </div>
                    <div>
                      <label for='staffAddDescrip' style={{'display': 'block'}}>个人描述</label>
                      <textarea ref='addDescrip' id='staffAddDescrip' type='text'></textarea>
                    </div>
                    <p ref="tips" className='tips' >提交成功</p>
                    <p ref='tipsUnDone' className='tips'>请录入完整的人员信息</p>
                    <p ref='tipsUnAge' className='tips'>请录入正确的年龄</p>
                    <div>
                      <button>提交</button>
                    </div>
                </form>
              </div>
            )
        }
    }

    代码看起来比较长,其实就是一个html表单,这个步骤基本都是不需要太多思考的操作,代码也没有任何理解上的难度,记住,我们现在就是要把整个框架搭起来,做一个静态版的应用!同样的,呈现出最终的样式,需要一些css,自行参考源代码。呈现的样子见图三最下面的蓝色方框。

    StaffDetail

    通常情况下,该组件是不显示的,只有当用户点击某条目的详情的时候,我用了一种动画效果将该组件’浮现出来’。方法就是在css中将该组件的z-index设置为一个很大的值,比如100,然后通过逐渐改变背景透明度的动画实现浮现的效果。目前我们只需要做一个静态版的React,尚未实现用户点击操作的交互,所以这里只需要创建以下js文件,并在css中将.overLay的display设置为none就可以了,源码中的css文件已经做好了。

    
    import React from 'react';
    export default class StaffDetail extends React.Component{
    
        render(){
          let staffDetail = this.props.staffDetail;  
          if(!staffDetail)
            return null;
    
          return (
              <div className="overLay">
                <h4 style={{'text-align':'center'}}>点击'完成'保存修改,点击'关闭'放弃未保存修改并退出.</h4>
                <hr/>
                <table ref="editTabel">
                  <tbody>
                    <tr>
                      <th>姓名</th>
                      <td><input id='staffEditName' type="text" defaultValue={staffDetail.info.name}></input></td>
                    </tr>
                    <tr>
                      <th>年龄</th>
                      <td><input id='staffEditAge' type="text" defaultValue={staffDetail.info.age}></input></td>
                    </tr>
                    <tr>
                      <th>性别</th>
                      <td>
                        <select ref='selSex' id='staffEditSex'>
                          <option value="男"></option>
                          <option value="女"></option>
                        </select>
                      </td>
                    </tr>
                    <tr>
                      <th>身份</th>
                      <td>
                        <select ref="selId" id='staffEditId'>
                          <option value="主任">主任</option>
                          <option value="老师">老师</option>
                          <option value="学生">学生</option>
                          <option value="实习">实习</option>
                        </select>
                      </td>
                    </tr>
                    <tr>
                      <th>个人描述</th>
                      <td><textarea id='staffEditDescrip' type="text" defaultValue={staffDetail.info.descrip}></textarea></td>
                    </tr>
                  </tbody>
                </table>
                <p ref='Dtips' className='tips'>修改成功</p>
                <p ref='DtipsUnDone' className='tips'>请录入完整的人员信息</p>
                <p ref='DtipsUnAge' className='tips'>请录入正确的年龄</p>
                <button>完成</button>
                <button>关闭</button>
              </div>
          );
        }
    }

    和staffFooter类似,这里主要就是一个表单。

    ManageSystem

    子组件都已经做好了,接下来就是最外层的容器了。按部就班,新建一个ManageSystem.js:

    
    import React from 'react';
    import StaffHeader from './StaffHeader.js';
    import StaffItemPanel from './StaffItemPanel.js';
    import StaffFooter from './StaffFooter.js';
    import StaffDetail from './StaffDetail.js';
    
    var rawData = [{ info: {descrip:'我是一匹来自远方的狼。', sex: '男', age: 20, name: '张三', id: '主任'}},
                   { info: {descrip:'我是一匹来自远方的狼。', sex: '女', age: 21, name: '赵静', id: '学生'}},
                   { info: {descrip:'我是一匹来自远方的狼。', sex: '女', age: 22, name: '王二麻', id: '学生'}},
                   { info: {descrip:'我是一匹来自远方的狼。', sex: '女', age: 24, name: '李晓婷', id: '实习'}},
                   { info: {descrip:'我是一匹来自远方的狼。', sex: '男', age: 23, name: '张春田', id: '实习'}},
                   { info: {descrip:'我是一匹来自远方的狼。', sex: '男', age: 22, name: '刘建国', id: '学生'}},
                   { info: {descrip:'我是一匹来自远方的狼。', sex: '男', age: 24, name: '张八', id: '主任'}},
                   { info: {descrip:'我是一匹来自远方的狗。', sex: '男', age: 35, name: '李四', id: '老师'}},
                   { info: {descrip:'我是一匹来自远方的猪。', sex: '男', age: 42, name: '王五', id: '学生'}},
                   { info: {descrip:'我是一匹来自远方的牛。', sex: '男', age: 50, name: '赵六', id: '实习'}},
                   { info: {descrip:'我是一匹来自远方的马。', sex: '男', age: 60, name: '孙七', id: '实习'}}];
    
    class App extends React.Component {
    
        render(){
          return (
            <div>
              <StaffHeader/>
              <StaffItemPanel items={rawData} />
              <StaffFooter/>
              <StaffDetail/>
            </div>
          );
        }
    }
    
    React.render(<App />, document.getElementById('app'));

    以上代码中rawData是演示数据,生产中的数据应该从数据库获得,这里为了简便,直接生成了11条演示用的数据。

    第三步:编译并打包

    在第二步中,我们已经生成了各个component以及subcomponent。主要的任务已经完成了,这一步是做什么的呢?

    简单地说,上文中我们编写React Component的过程中,使用了es6和JSX的语法。(特别值得一提的是es6的Module,终于从语言规格上让Javascript拥有了模块功能。如今js渐入佳境,学习es6是十分重要且值得的!)但这些目前是不能被浏览器直接支持的。所以在使用之前,要先经过’编译’,这个过程我们是使用Babel完成的。

    关于Babel,正如其官网所言–Babel is a Javascript compiler.本应用中,它帮我们完成了es6以及JSX的编译。只不过在本例中babel是以webpack的loader的方式出现的。

    关于webpack这里也不多言了–webpack is a module bundler.请大家自己查阅相关资料。

    安装依赖项

    在这里,首先执行以下命令,安装开发依赖:

    npm install
    

    该命令会自动读取当前目录下的package.json文件,并自行安装其中的依赖项。文件内容如下:

    {
      "name": "StaffManage",
      "version": "1.0.0",
      "description": "",
      "main": "",
      "scripts": {
        "start": "webpack"
      },
      "author": "WYH",
      "license": "ISC",
      "devDependencies": {
        "babel-core": "^6.14.0",
        "babel-loader": "^6.2.5",
        "babel-preset-es2015": "^6.14.0",
        "babel-preset-react": "^6.11.1",
        "webpack": "^1.13.2"
      }
    }
    

    更具体地说,其中的开发依赖项就是

      "devDependencies": {
        "babel-core": "^6.14.0",
        "babel-loader": "^6.2.5",
        "babel-preset-es2015": "^6.14.0",
        "babel-preset-react": "^6.11.1",
        "webpack": "^1.13.2"
      }
    

    编译打包

    安装开发依赖项后,接下来就是使用webpack打包了,webpack的loader在解析文件的时候会自动使用babel对文件进行编译。配置文件如下:

    module.exports = {
        entry: __dirname + '/src/ManageSystem.js',
        output: {
            path: __dirname + '/build',
            filename: "bundle.js"
        },
        externals: {
            'react': 'React'
        },
        devtool: 'eval-source-map',  //生成source file
        module: {
            loaders: [
              {
                test: /\.js$/,
                exclude: /node_modules/,
                loader: 'babel',
                query: {
                  presets: ['es2015', 'react']
                }
              }
            ]
        }
    };
    

    将第二步中的所有组件都放到当前目录下的src目录中,目录结构可以参考源代码,然后执行以下命令:

    npm start
    

    该命令也是在package.json中指定的。

    "scripts": {
      "start": "webpack"
    }
    

    好了,在build目录下应该已经生成bundle.js文件,这就是我们打包好的文件,我们只需要在html中引用它就行了。

    在当前目录下生成html文件如下:

    <!DOCTYPE html>
    <html lang="zh-CN">
      <head>
        <meta charset="utf-8">
        <title>人员管理</title>
        <link href="build/style.css" rel="stylesheet" />
    
      </head>
      <body>
          <div id="app">
          </div>
    
          <script src="http://cdn.bootcss.com/react/0.13.3/react.min.js"></script>
          <script src="build/bundle.js"></script>
      </body>
    </html>

    接下来在浏览器中打开index.html看看吧,静态版的React已经生成了,只是还没有动态交互而已。至此,已经完成了构建静态版的React的工作,大框架已经建立,接下来我们让它动起来!

    第四步:添加STAFF类

    本文应用涉及的功能有排序,筛选、新增、删除、修改以及关键字搜索等。功能较多,业务逻辑有些复杂。为了让React集中精力完成view层的事情,我们这里新建一个STAFF类来完成业务逻辑。

    Javascript中,类的实现是基于其原型继承机制的。但在es6中,提供了更接近传统面向对象语言的写法,引入了类(class)的概念。我们可以通过class关键字来定义类。实际上,es6的class只是一个语法糖(syntax sugar),它的绝大部分功能,es5均可以做到。而引入的class写法,是为了让对象的写法更加清晰、更加具有面向对象的感觉。

    接下来我们新建一个STAFF.js文件:

    
    class staffItem {
        constructor(item){
            this.info = {};
            this.info.name = item.name;
            this.info.age = item.age || 0;
            this.info.sex = item.sex;
            this.info.id = item.id;
            this.info.descrip = item.descrip || '';
            this.key = ++staffItem.key;
        }
    }
    staffItem.key = 0;
    
    export default class STAFF {
    
        constructor(){
            this.allStaff = [
                new staffItem(STAFF.rawData[0]),
                new staffItem(STAFF.rawData[1]),
                new staffItem(STAFF.rawData[2]),
                new staffItem(STAFF.rawData[3]),
                new staffItem(STAFF.rawData[4]),
                new staffItem(STAFF.rawData[5]),
                new staffItem(STAFF.rawData[6]),
                new staffItem(STAFF.rawData[7]),
                new staffItem(STAFF.rawData[8]),
                new staffItem(STAFF.rawData[9]),
                new staffItem(STAFF.rawData[10])
            ];
            this.staff = this.allStaff;
        }
    }
    
    STAFF.rawData = [{ descrip:'我是一匹来自远方的狼。', sex: '男', age: 20, name: '张三', id: '主任'},
                     { descrip:'我是一匹来自远方的狼。', sex: '女', age: 21, name: '赵静', id: '学生'},
                     { descrip:'我是一匹来自远方的狼。', sex: '女', age: 22, name: '王二麻', id: '学生'},
                     { descrip:'我是一匹来自远方的狼。', sex: '女', age: 24, name: '李晓婷', id: '实习'},
                     { descrip:'我是一匹来自远方的狼。', sex: '男', age: 23, name: '张春田', id: '实习'},
                     { descrip:'我是一匹来自远方的狼。', sex: '男', age: 22, name: '刘建国', id: '学生'},
                     { descrip:'我是一匹来自远方的狼。', sex: '男', age: 24, name: '张八', id: '主任'},
                     { descrip:'我是一匹来自远方的狗。', sex: '男', age: 35, name: '李四', id: '老师'},
                     { descrip:'我是一匹来自远方的猪。', sex: '男', age: 42, name: '王五', id: '学生'},
                     { descrip:'我是一匹来自远方的牛。', sex: '男', age: 50, name: '赵六', id: '实习'},
                     { descrip:'我是一匹来自远方的马。', sex: '男', age: 60, name: '孙七', id: '实习'}];

    在STAFF.js中我们实际上创建了2个类,为了实现更好的’封装性’,我们将每一个人员条目单独作为一个staffItem类,该对象中包含了该人员的所有信息,在本应用中包含他的姓名、年龄、性别、身份、个人描述等,实践中我们可以加入类似入职时间,福利薪酬,个人经历等信息。另外还有一个key值,它是一个类变量,这个值是唯一标识该staffItem用的。

    在第二步,我们在ManageSystem.js中伪造了一些数据,现在我们也把它搬到STAFF中。毕竟React不是存数据用的。

    在STAFF类的构造函数中,创建了2个实例变量,一个是allStaff,其中存储所有staffItem;一个是staff,它是最终需要给React展示的数据,是经过用户筛选操作、关键字搜索操作之后得到的人员数组。之所以这么设计变量也是为了后面的筛选、搜索等功能。在这里我们尚无这些操作的逻辑,直接将allStaff赋给staff即可。

    好了,接下来在ManageSystem中引入Staff.js,并初始化state:

    
    import React from 'react';
    import StaffHeader from './StaffHeader.js';
    import StaffItemPanel from './StaffItemPanel.js';
    import StaffFooter from './StaffFooter.js';
    import StaffDetail from './StaffDetail.js';
    
    import STAFF from './STAFF.js';
    
    class App extends React.Component {
    
        constructor(){
            super();
            this.state = {
                staff : new Staff
            };
        }
    
        render(){
          return (
            <div>
              <StaffHeader/>
              <StaffItemPanel items={this.state.staff.staff} />
              <StaffFooter/>
              <StaffDetail/>
            </div>
          );
        }
    }
    
    React.render(<App />, document.getElementById('app'));    

    在构造函数中,new了一个STAFF类,然后将this.state.staff.staff传入<StaffItemPanel/>的items属性。

    然后重新编译打包:

    npm start
    

    再次在浏览器打开index.html文件,虽然还是一个静态版的React,不过它已经变得更加模块化和’专一’了,结构也更加漂亮。

    第五步:完成新增人员功能

    关于state

    上文说过,state是为交互而生的。React是自上而下的单向数据流,state通常由上层组件拥有并控制,state的变化将触发建立在该state上的一系列自上而下的组件更新。注意,组件只能update它自己的state,如果下层组件的操作希望改变应用的状态,形成一个inverse data flow–反向数据流,我们需要从上层组件传入一个回调函数。关于state如何确定,可以参考官网一篇文章Thinking in React。接下来我们看人员功能添加是如何完成的。

    实现人员新增功能

    真正让React动起来,不妨从新增人员逻辑开始吧,这个功能比较纯粹,和其他业务耦合度不高。重新打开StaffFooter.js,加入部分代码:

    
    import React from 'react';
    export default class StaffFooter extends React.Component{
    
        handlerAddClick(evt){
            evt.preventDefault();
            let item = {};
            let addForm = React.findDOMNode(this.refs.addForm);
            let sex = addForm.querySelector('#staffAddSex');
            let id = addForm.querySelector('#staffAddId');
    
            item.name = addForm.querySelector('#staffAddName').value.trim();
            item.age = addForm.querySelector('#staffAddAge').value.trim();
            item.descrip = addForm.querySelector('#staffAddDescrip').value.trim();
            item.sex = sex.options[sex.selectedIndex].value;
            item.id = id.options[id.selectedIndex].value;
    
            /*
             *表单验证
             */
            if(item.name=='' || item.age=='' || item.descrip=='') {
                let tips = React.findDOMNode(this.refs.tipsUnDone);
                tips.style.display = 'block';
                setTimeout(function(){
                    tips.style.display = 'none';
                }, 1000);
                return;
            }
            //非负整数
            let numReg = /^\d+$/;
            if(!numReg.test(item.age) || parseInt(item.age)>150) {
                let tips = React.findDOMNode(this.refs.tipsUnAge);
                tips.style.display = 'block';
                setTimeout(function(){
                    tips.style.display = 'none';
                }, 1000);
                return;
            }
    
            this.props.addStaffItem(item);
            addForm.reset();
    
            //此处应在返回添加成功信息后确认
            let tips = React.findDOMNode(this.refs.tips);
            tips.style.display = 'block';
            setTimeout(function(){
                tips.style.display = 'none';
            }, 1000);
        }
    
        render(){
            return (
              <div>
                <h4 style={{'text-align':'center'}}>人员新增</h4>
                <hr/>
                <form ref='addForm' className="addForm">
                    <div>
                      <label for='staffAddName' style={{'display': 'block'}}>姓名</label>
                      <input ref='addName' id='staffAddName' type='text' placeholder='Your Name'/>
                    </div>
                    <div>
                      <label for='staffAddAge' style={{'display': 'block'}}>年龄</label>
                      <input ref='addAge' id='staffAddAge' type='text' placeholder='Your Age(0-150)'/>
                    </div>
                    <div>
                      <label for='staffAddSex' style={{'display': 'block'}}>性别</label>
                      <select ref='addSex' id='staffAddSex'>
                        <option value='男'></option>
                        <option value='女'></option>
                      </select>
                    </div>
                    <div>
                      <label for='staffAddId' style={{'display': 'block'}}>身份</label>
                      <select ref='addId' id='staffAddId'>
                        <option value='主任'>主任</option>
                        <option value='老师'>老师</option>
                        <option value='学生'>学生</option>
                        <option value='实习'>实习</option>
                      </select>
                    </div>
                    <div>
                      <label for='staffAddDescrip' style={{'display': 'block'}}>个人描述</label>
                      <textarea ref='addDescrip' id='staffAddDescrip' type='text'></textarea>
                    </div>
                    <p ref="tips" className='tips' >提交成功</p>
                    <p ref='tipsUnDone' className='tips'>请录入完整的人员信息</p>
                    <p ref='tipsUnAge' className='tips'>请录入正确的年龄</p>
                    <div>
                      <button onClick={this.handlerAddClick.bind(this)}>提交</button>
                    </div>
                </form>
              </div>
            )
        }
    }

    我们在提交的按钮上绑定了点击事件。点击提交按钮后,执行以下函数:

    handlerAddClick(evt){
        evt.preventDefault();
        let item = {};
        let addForm = React.findDOMNode(this.refs.addForm);
        let sex = addForm.querySelector('#staffAddSex');
        let id = addForm.querySelector('#staffAddId');
    
        item.name = addForm.querySelector('#staffAddName').value.trim();
        item.age = addForm.querySelector('#staffAddAge').value.trim();
        item.descrip = addForm.querySelector('#staffAddDescrip').value.trim();
        item.sex = sex.options[sex.selectedIndex].value;
        item.id = id.options[id.selectedIndex].value;
    
        /*
         *表单验证
         */
        if(item.name=='' || item.age=='' || item.descrip=='') {
            let tips = React.findDOMNode(this.refs.tipsUnDone);
            tips.style.display = 'block';
            setTimeout(function(){
                tips.style.display = 'none';
            }, 1000);
            return;
        }
        //非负整数
        let numReg = /^\d+$/;
        if(!numReg.test(item.age) || parseInt(item.age)>150) {
            let tips = React.findDOMNode(this.refs.tipsUnAge);
            tips.style.display = 'block';
            setTimeout(function(){
                tips.style.display = 'none';
            }, 1000);
            return;
        }
    
        this.props.addStaffItem(item);
        addForm.reset();
    
        //此处应在返回添加成功信息后确认
        let tips = React.findDOMNode(this.refs.tips);
        tips.style.display = 'block';
        setTimeout(function(){
            tips.style.display = 'none';
        }, 1000);
    }
    

    这里我们获取并简单处理了表单,特别注意

    this.props.addStaffItem(item);
    

    这一行代码,就是调用了ManageSystem通过prop属性传入的回调函数。在ManageSystem中加入相关代码:

    
    import React from 'react';
    import StaffHeader from './StaffHeader.js';
    import StaffItemPanel from './StaffItemPanel.js';
    import StaffFooter from './StaffFooter.js';
    import StaffDetail from './StaffDetail.js';
    
    import Staff from './STAFF.js';
    
    
    class App extends React.Component {
        constructor(){
            super();
            this.state = {
                staff : new Staff,
                staffDetail: null
            };
        }
    
        //增
        addStaffItem(item){
            this.setState({
                staff: this.state.staff.addStaffItem(item)
            });
        }
    
        render(){
          return (
            <div>
              <StaffHeader/>
              <StaffItemPanel items={this.state.staff.staff}}/>
              <StaffFooter addStaffItem={this.addStaffItem.bind(this)}/>
              <StaffDetail/>
            </div>
          );
        }
    }
    
    React.render(<App />, document.getElementById('app'));

    <StaffFooter addStaffItem={this.addStaffItem.bind(this)}/>中传入了addStaffItem方法。

    //增
    addStaffItem(item){
        this.setState({
            staff: this.state.staff.addStaffItem(item)
        });
    }
    

    中更新了自己的state。只不过具体的逻辑是在STAFF类的方法中完成的。

    STAFF.js:

    
    export default class STAFF {
    
        constructor(){
            this.allStaff = [
                new staffItem(STAFF.rawData[0]),
                new staffItem(STAFF.rawData[1]),
                new staffItem(STAFF.rawData[2]),
                new staffItem(STAFF.rawData[3]),
                new staffItem(STAFF.rawData[4]),
                new staffItem(STAFF.rawData[5]),
                new staffItem(STAFF.rawData[6]),
                new staffItem(STAFF.rawData[7]),
                new staffItem(STAFF.rawData[8]),
                new staffItem(STAFF.rawData[9]),
                new staffItem(STAFF.rawData[10])
            ];
            this.staff = this.allStaff;
        }
    
        //增
        addStaffItem(item) {
            let newItem = new staffItem(item);
            this.allStaff.push(newItem);
            this.staff = this.allStaff;
            return this;
        }
    }

    重新编译打包生成bundle.js文件:

    npm start
    

    再次在浏览器中打开index.html文件,试试我们新添加的人员添加功能吧!

    第六步:完成关键字搜索功能

    类似第五步新人员的添加,我们首先给StaffHeader中的搜索输入框绑定一个onChange事件,每当搜索内容改变时,触发该函数:

    StaffHeader.js

    
    import React from 'react';
    export default class StaffHeader extends React.Component{
    
        //search
        handlerSearch(){
            let bar = React.findDOMNode(this.refs.searchBar);
            let value = bar.value;
            this.props.searchStaff(value);
        }
    
        render(){
            return (
              <div>
                  <h3 style={{'text-align':'center'}}>人员管理系统</h3>
                  <table className="optHeader">
                    <tbody>
                      <tr>
                        <td className="headerTd"><input ref='searchBar' onChange={this.handlerSearch.bind(this)} type='text' placeholder='Search...' /></td>
                        <td className="headerTd">
                            <label for='idSelect'>人员筛选</label>
                            <select id='idSelect'>
                                <option value='0'>全部</option>
                                <option value='1'>主任</option>
                                <option value='2'>老师</option>
                                <option value='3'>学生</option>
                                <option value='4'>实习</option>
                            </select>
                        </td>
                        <td>
                            <label for='orderSelect'>排列方式</label>
                            <select id='orderSelect'>
                                <option value='0'>身份</option>
                                <option value='1'>年龄升</option>
                                <option value='2'>年龄降</option>
                            </select>
                        </td>
                      </tr>
                    </tbody>
                  </table>
              </div>
            );
        }
    }

    同样在事件处理函数中,调用了通过props属性传入的回调函数searchStaff:

    //search
    handlerSearch(){
        let bar = React.findDOMNode(this.refs.searchBar);
        let value = bar.value;
        this.props.searchStaff(value);
    }
    

    逐步完善ManageSystem以及STAFF类:

    ManageSystem.js:

    
    class App extends React.Component {
        constructor(){
            super();
            this.state = {
                staff : new Staff,
                staffDetail: null
            };
        }
    
        //增
        addStaffItem(item){
            this.setState({
                staff: this.state.staff.addStaffItem(item)
            });
        }
    
        /*
         * 搜索
         */
        searchStaff(word) {
            this.setState({
                staff: this.state.staff.searchStaff(word)
            });
        }
    
        render(){
          return (
            <div>
              <StaffHeader searchStaff={this.searchStaff.bind(this)} />
              <StaffItemPanel items={this.state.staff.staff}}/>
              <StaffFooter addStaffItem={this.addStaffItem.bind(this)}/>
              <StaffDetail/>
            </div>
          );
        }
    }

    STAFF.js

    
    export default class STAFF {
    
        constructor(){
            this.allStaff = [
                new staffItem(STAFF.rawData[0]),
                new staffItem(STAFF.rawData[1]),
                new staffItem(STAFF.rawData[2]),
                new staffItem(STAFF.rawData[3]),
                new staffItem(STAFF.rawData[4]),
                new staffItem(STAFF.rawData[5]),
                new staffItem(STAFF.rawData[6]),
                new staffItem(STAFF.rawData[7]),
                new staffItem(STAFF.rawData[8]),
                new staffItem(STAFF.rawData[9]),
                new staffItem(STAFF.rawData[10])
            ];
            this.staff = this.allStaff;
            this.word = '';  //搜索关键字
        }
    
        //增
        addStaffItem(item) {
            let newItem = new staffItem(item);
            this.allStaff.push(newItem);
            this.staff = this.allStaff;
            return this;
        }
    
        //搜索
        searchStaff(word){
            this.word = word;
            this.staff = this.allStaff;
            //在staff中搜索
            this.staff = this.staff.filter(item => {
                return item.info.name.indexOf(word)!=-1 || 
                       (item.info.age+'').indexOf(word)!=-1 || 
                       item.info.id.indexOf(word)!=-1 ||
                       item.info.sex.indexOf(word)!=-1;
            });
            return this;
        }
    }

    依据关键字的搜索功能至此也完成了。

    完成接下来的功能

    作为示例,第五步以及第六步完成了添加人员以及关键字搜索功能。随后随着功能的不断添加,最终代码的实现会有微小的调整。实现的方法大同小异,请大家对照源码,依照上面的方法逐步完整整个应用。我相信你实现了每一个细节之后,对面入门React一定会有十分大的帮助。

    展开全文
  • React入门(一)

    2018-05-23 02:10:50
    之前在进行前端工作时,也做过几个使用React框架的前端项目,最近的毕业设计也是做了一个react框架的电子商务平台,答辩完后发现个人对于React还没有做一个总结,为了准备以后的面试,在最近几天慢慢的整理出来吧。...

          之前在进行前端工作时,也做过几个使用React框架的前端项目,最近的毕业设计也是做了一个react框架的电子商务平台,答辩完后发现个人对于React还没有做一个总结,为了准备以后的面试,在最近几天慢慢的整理出来吧。

          首先是一些众所周知的背景说明:React 起源于 Facebook 的内部项目,因为该公司的一个小任性,不满意当时已有的所有 JavaScript MVC 框架,决定自己写一套,用来架设Instagram 的网站。做出来后发现还挺好用的,于是,react在2013年5月开源了。

          接下来是React的一些大体特性介绍。React相对于其他的框架,它跟Vue一样,有自己的一套路由机制来实现自己的单页面。说到单页面,就得附带的说下React的Virtual DOM(虚拟DOM树)。做过前端开发的人都知道,DOM操作是最昂贵的操作之一,在性能优化中,减少对DOM树的访问修改是很重要的一部分。怎么理解虚拟DOM呢:

           在HTML中存在 ---- <ul class="list">

                                                <li class="item">first</li>

                                                <li class="item">second</li>

                                           </ul>

    <ul class="list">                                           <li class="item">first</li>                                     <li class="item">second</li>                                   </ul>

            将这个真实的DOM抽象为一个JavaScript的对象,即虚拟DOM,则我们可以把上面的真实DOM构造为:

                                var element = {

                                        element: 'ul',

                                        props: {

                                            className: 'list'

                                        },

                                        children: [

                                            { element: 'li', props: {className: 'li'}, children: ['first'] },

                                            { element: 'li', props: {className: 'li"}, children: ['second'] }

                                         ]

                                }

    var element = {                               element: 'ul',                                 props: {                                   className: 'list'
    },                                   children: [                                       { element: 'li', props:{className:'li'
    },
    children: ['first'] },                                      { element: 'li', props: {className: 'li"}, children: ['second'] }                                ]
    }

            当我们想要在这里面删除first、second,然后添加一个third时,DOM操作就是逐步删除first、second,添加third,而如果是虚拟DOM树,将比较原有的和变化后的差距,保留之前存在first、second的对象,然后生成一个新的具有third的对象,通过JS算法进行比较然后修改。至于如何将虚拟DOM转为真实DOM,只要将element对象(具有TagName、props、children属性/*代码仅为示例*/),通过JS的各种方法如setAttribute、render、appendChild、createTextNode、createElement即可。

            粗略的说下了虚拟DOM的皮毛就这么多了。。。在下一篇再深入的剖析,React的各种相关内容,也会慢慢的整理出来。

            


    展开全文
  • react 之零基础入门

    2019-07-11 10:13:20
    付出,不一定会有收获;不付出,却一定不会有收获,...import React from "react" import {Component) from 'react' class Comp1 extends Component{ constructor(..args){ super(..args) } render(){ ...

    付出,不一定会有收获;不付出,却一定不会有收获,不要奢望出现奇迹

    react 组件写法非常简单

    import React from "react"
    import {Component) from 'react'
    
    class Comp1 extends Component{
    	
    		constructor(..args){
    			super(..args)
    		}
    
    		render(){
    			return(
    				<div></div>
    			);
    		}
    }
    
    export default Comp1;
    

     以上就是jsx 写法,顾名思义就是js + xml ,

    其中render 方法返回值,就是jsx 写法,我的理解就是写html 无非, class 变成className for 变成htmlFor 本质没啥不通

    感觉就是在写js ,写多了,也就会了!

    ————————————————————————————————

    组件的引用也非常简单,

    引入使用,就行了

     

    比我们的vue 少了一部,就是注册,vue中还要在component 中注册!

     

    ————————————————————————————————————————————

     

     

    以上都不重要,都是细节小知识点,随便找个教程都能很轻松的学会,这也是现在社会的好处,资源到处都有,就像我一样

    基本上啥都有,所以各位看客,需要任何虚拟资料都可以加我qq 1981389505 去免费获取所要的资料,

    因为我有一套爬虫系统支撑,不扯了,我们继续

    ————————————————————————————————————————————

    下面是 ,两个重点,就是  redux (全局 的状态管理) ---

    react于VUE类比
    功能 react vue
    状态管理  redux vuex
    路由 react-router-dom vue-router

     

    我们无论去使用那个组件技术,上面的 状态管理和路由都必须拿下,要不然,你基础都不会也跑不起来嘛

    所以不要着急,我们一点点前行!

     

    下面就是redux使用!

    我们先画一个整体的流程图:

     

    上面是我用画图软件画的,是有点Low,凑合看吧!

     

    
    
    import {createStore} from 'redux';
    
    
    // 处理请求的回调方法,我感觉很开心,因为一次性就把redux 的写法写正确了,可见我的js 水平很高
    function reducer1(state,action){
    	if(!state){
    		state = {
    			name:'xiaoming',
    			age:28
    		}
    	}
    
    	const type = action.type;
    	switch(type){
    		case "show":
    		return {
    			...state,
    			name:action.param
    		}
    		break;
    	}
    	return state;
    }
    
    const store = createStore(reducer1);
    
    export default store;

     

     

    import React from 'react';
    import ReactDOM from 'react-dom';
    
    import App from './App';
    
    import store from './store'
    import {Provider} from "react-redux"
    
    ReactDOM.render(<Provider store={store}><App /></Provider>, document.getElementById('root'));
    

     

    以上两文件,第一个文件,定义的就是全局的状态管理器

    第一个文件包含了,全局的状态管理函数!

     

    全局数据放state 中, 对数据的操作,都交给 上面的switch 中去处理!

    第二个文件主要时<Provider/> 谁被它包裹,谁就拥有了连接全局资源的权利,谁就用于了数据,和对数据处理函数!

     

    App.js

    导出的时候,这么写就行

    数据都在state 中了,

    对数据的处理函数,你可以自己写,上面的show 方法就是一个action

    调用

    最终会到了reducer 函数中

    根据action 的类型处理对应的逻辑!

    好,大概就是组件连接全局状态器

     

    发送action ,一个大JSON就是一个action ,然后reducer 函数,根据action。类型去处理对应的数据!

     

    redux 就略讲到这里,没基础的肯定看不懂这篇,只有看视频了!

    建议去看:

    http://www.itjiaocheng.com/youzhi/25805.html

    看第六期就行了,里面讲的很清楚!(标注不是做广告)

    因为我所学的都是从石川那里学的,很清晰!

    这篇先写到这里,下一个就是react 的路由,我觉得有必要去搞清楚

    基本写法, 嵌套写法,接受参数??

    我们放到下一篇

    再次一个格言: 

    每个人都会累,没人能为你承担所有悲伤,人总有一段时间要学会自己长大

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    展开全文
  • 第1章 介绍课程目标和学习内容包括...1-1 课程导学第2章 知识储备2-1 介绍React开发环境2-2 ES6常用语法2-3 express+mongodb基础2-4 express+mongodb基础第3章 React基础知识回顾3-1 React基础知识回顾1-入门例子3-2...

    第1章 介绍课程目标和学习内容
    包括课程概述、课程安排、学习前提、讲授方式等方面的介绍,最后演示了整个招聘App的功能,让同学们对课程项目有一个直观的了解。
    1-1 课程导学
    第2章 知识储备
    2-1 介绍React开发环境
    2-2 ES6常用语法
    2-3 express+mongodb基础
    2-4 express+mongodb基础

    第3章 React基础知识回顾
    3-1 React基础知识回顾1-入门例子
    3-2 React基础知识回顾2-组件之间传递数据
    3-3 React基础知识回顾3-组件内部 state
    3-4 React基础知识回顾4-事件
    3-5 React基础知识回顾5-React生命周期
    3-6 React基础知识回顾6-安装 CHROME 扩展
    3-7 antd-mobile 组件使用

    第4章 Redux状态管理与React-router
    4-1 Redux状态管理1-结合小例子看 Redux 是什么?
    4-2 Redux状态管理2-Redux 如何和 React 一起用
    4-3 Redux状态管理3-优化-组件解耦
    4-4 Redux状态管理4-更进一步,让 Redux 可以处理异步
    4-5 Redux状态管理5-Chrome 中 Redux 调式工具
    4-6 Redux状态管理6-使用 React-redux
    4-7 Redux状态管理7-使用 React-redux(Connect 可以用装饰器的方法来书写)
    4-8 react-router4 路由 01-初识 React-router4
    4-9 react-router4 路由 02-React-router4 其他组件
    4-10 react-router4 路由 03-和 Redux 配合-复杂 Redux 应用1
    4-11 react-router4 路由 04-和 Redux 配合-复杂 Redux 应用2
    4-12 react-router4 路由 05-和 Redux 配合-补充

    第5章 需求分析
    5-1 需求分析
    5-2 前后端联调1
    5-3 前后端联调2

    第6章 登录注册
    6-1 登录注册-课程内容介绍
    6-2 登录注册-登录注册页面实现
    6-3 登录注册-判断路由
    6-4 登录注册-用户信息校验,跳转登录
    6-5 登录注册-注册交互实现
    6-6 登录注册-注册请求发送
    6-7 登录注册-数据库模型建立
    6-8 登录注册-express注册功能实现
    6-9 登录注册-注册前后端联调
    6-10 登录注册-注册跳转+密码加密实现
    6-11 登录注册-登录注册实现
    6-12 登录注册-cookie保存登录状态

    第7章 完善信息
    7-1 完善信息-boss信息完善页面
    7-2 完善信息-boss 信息完善页面后端
    7-3 完善信息-牛人信息完善和组件属性类型检测

    第8章 牛人列表和BOSS列表
    8-1 牛人列表-应用骨架
    8-2 牛人列表-导航和跳转
    8-3 牛人列表-牛人列表
    8-4 牛人列表-使用 redux 管理牛人列表

    第9章 个人中心
    9-1 boss列表和组件优化
    9-2 个人中心信息展示1
    9-3 个人中心信息展示2
    9-4 清除cookie登录状态
    9-5 注销时清空redux数据
    9-6 使用高级组件完善登录流程--概念理解-函数式编程
    9-7 简单的高阶组件demo
    9-8 使用imoocFrom高阶组件优化代码

    第10章 聊天详情
    10-1 socket.io简介
    10-2 socket.io前后端联通
    10-3 前后端实时显示消息
    10-4 聊天页面redux链接
    10-5 聊天功能实现-上
    10-6 聊天功能实现-下
    10-7 聊天未读消息数实时展示
    10-8 聊天头像显示
    10-9 修正未读消息数量
    10-10 发送emoji表情

    第11章 聊天列表
    11-1 聊天信息根据用户分组
    11-2 聊天列表展示
    11-3 显示未读消息数
    11-4 最新消息排序

    第12章 构建自己的 redux
    12-1 消息未读数量更新1
    12-2 消息维度数量更新2
    12-3 React进阶
    12-4 迷你redux实现
    12-5 context简介1
    12-6 react-redux实现1
    12-7 react-redux实现2
    12-8 迷你react-redux实现
    12-9 中间件机制的实现
    12-10 多个中间件合并
    12-11 定制中间件arrThunk
    12-12 总结redux+react-redux代码

    第13章 代码优化和进阶
    13-1 单组件
    13-2 定制shouldComponentUpdae
    13-3 immutablejs存在的意义和使用
    13-4 reselect优化redux选择器
    13-5 遍历数组的key
    13-6 服务端渲染ssr介绍

    第14章 项目总结,回顾和展望
    14-1 eslint代码规范
    14-2 async+await优化异步代码
    14-3 使用Ant motion做React动画解决方案
    14-4 打包编译
    14-5 使用babel-node在后端支持jsx环境
    14-6 服务端渲染renderToString用法
    14-7 客户端代码改造
    14-8 服务端SSR代码改造
    14-9 小问题修复
    14-10 React16新特性及错误处理1
    14-11 React16错误处理2
    14-12 React16服务端渲染新Api
    14-13 课程总结

    下载地址:百度网盘

    展开全文
  • React基础入门

    2017-02-17 00:06:14
    react入门

    一、客户端引入React库

    react在0.14版本时,将库拆封成了两个部分:react.js和react-dom.js。

    • react.js中包含 React.createElement、 .createClass、 .Component, .PropTypes, .Children 这些 API,主要用来创建组件。
    • react-dom.js中包含 ReactDOM.render、 .unmountComponentAtNode、 .findDOMNode,主要用来将节点渲染到节点,以及找到真实的DOM节点。
    <script type="text/javascript" src="../js/react.min.js"></script>
    <script type="text/javascript" src="../js/react-dom.min.js"></script>
    <script type="text/javascript" src="../js/browser.min.js"></script>

    其中browser主要用来转义jsx语法,还有将es6转义成es5。


    二、jsx语法

    简单来说就是将js与html进行了混合。

    demo:

    var style = {
        color: 'red',
        border: '1px #000 solid',
        lineHeight: '50px'
    };
    var HelloMessage = React.createClass({
        render: function() {
            return <div style={style}>Hello {this.props.name || 'React'}</div>;
        }
    });
    
    ReactDOM.render(<HelloMessage name="World" />,document.body);

    三、React组件的生命周期

    1、初始化阶段

    var HelloWorld = React.createClass({
        getDefaultProps: function(){//只调用一次,实例之间共享引用
            console.log('getDefaultProps,1');
            return {name: 'Tom'};
        },
        getInitialState: function(){//初始化每个实例特有的状态
            console.log('getInitialState,2');
            return {myCount: count++, ready: false};
        },
        componentWillMount: function(){//render之前最后一次修改状态
            console.log('componentWillMount,3');
            this.setState({ready: true});
        },
        render: function() {//只能访问this.props和this.state,只有一个顶层组件,不允许修改状态和DOM输出
            console.log('render,4');
            return <p>Hello {this.props.name || 'World'} <br /> {''+this.state.ready} <br /> {'  '+this.state.myCount+'  '}</p>
        },
        componentDidMount:function(){//成功render并渲染完成真实DOM之后触发,可以修改真实的DOM
            console.log('componentDidMount,5');
            $(ReactDOM.findDOMNode(this)).append('surprise!');
        }
    });

    2、运行中阶段

    var HelloWorld = React.createClass({
        componentWillReceiveProps: function(newProps) {
            console.log('componentWillReceiveProps, 1');
            console.log(newProps);
        },
        shouldComponentUpdate: function() {
            console.log('shouldComponentUpdate, 2');
            return true;
        },
        componentWillUpdate: function(){
            console.log('componentWillUpdate, 3');
        },
        render: function() {//只能访问this.props和this.state,只有一个顶层组件,不允许修改状态和DOM输出
            console.log('render,4');
            return <p>Hello {this.props.name || 'World'} <br/></p>
        },
        componentDidUpdate:function(){//组件更新完后调用
            console.log('componentDidUpdate, 5');
            $(ReactDOM.findDOMNode(this)).append('surprise!');
        }
    });

    3、销毁阶段

    var HelloWorld = React.createClass({
        render: function() {//只能访问this.props和this.state,只有一个顶层组件,不允许修改状态和DOM输出
            console.log('render,4');
            return <p>Hello {this.props.name || 'World'} <br/></p>
        },
        componentWillUnmount:function(){
            console.log('BOOOOOOOOOOOOOOM!');
        }
    });

    四、组件的属性与状态

    属性: this.props,

    一个事物的性质与关系。
    属性是不可以由自己修改的,是父组件调用该组件或者创建实例时传递进来的。

    给一个组件传递属性的三种方法:

    1、通过键值对的方式

    <New name={'Jack'}></New>

    大括号中是一段js执行代码,可以使数字、字符串基本数据,也可以是三元表达式或者异或运算。

    2、通过react语法糖(…)展开一个对象

    var  properties = {name: 'Jack', age: 18};
    <New {...properties}></New>

    …的运算符号能将一个对象进行展开,相当于拿到了properties对象中的两个属性赋给该组件。

    3、使用setProps方法,该方法不建议使用,不能再组件内部修改属性,这违背了组件设计的原则

    var instacne = ReactDOM.render(<New />,document.body);
    instance.setProps({name: 'Jack'});

    在最新的React版本15中,setProps已经被弃用。

    状态:this.state,

    事物所处的状况。状态是由事物自行处理的,不断变化的,是一个事物的私有属性。

    与状态有关的方法:
    - getInitialState: 初始化每个实例特有的状态。
    - setState:更新组件的状态。使用setState会调用diff算法。

    属性与状态异同:

    相似点:
    - 都是JS纯对象
    - 都会触发render更新
    - 都具有确定性

    不同点:

    属性 状态
    是否从父组件获取初始值
    是否由父组件修改
    是否在组件内部设置默认值
    是否在组件内部修改
    是否设置子组件的初始值
    是否修改子组件的值

    状态和属性都会触发render更新,都是纯JS对象。
    - 状态:组件状态只和自己相关,既不受父组件也不受子组件影响
    - 属性:组件不能修改属性,只能从父组件获取属性,父组件也能修改它的属性

    根本的区别:组件在运行时需要修改的数据就是状态。

    展开全文
  • 所以决定做一个react入门总结。 首先,在实现crud操作前我们需要了解,React是如何操作修改数据,先看一个简单的demon,react是如何实现数据双向绑定(我理解的数据双向绑定) 一、简单的双向绑定 ...
  • React基础入门详解

    2019-05-27 23:01:06
    React项目的创建 1、 运行 cnpm i react react-dom -S 安装包 2、 在项目中导入两个相关的包: // 1. 在 React 学习中,需要安装 两个包 react react-dom // 1.1 react 这个包,是专门用来创建React组件、组件生命...
  • React入门学习

    2017-05-16 18:33:06
    React入门学习
  • React入门知识汇总

    2019-08-12 20:44:32
    React入门知识汇总开发环境的搭建组件(Component)组件之间通信(props与state)props   由于最近1个月在工作当中需要写前端的页面,于是用到了React,也算是入门了吧,同时组件库用到了公司内部的一些组件,...
  • React 入门实例教程

    2017-01-16 10:35:43
    React 。 上周,基于 ReactReact Native 发布,结果一天之内,就获得了 5000 颗星,受瞩目程度可见一斑。 React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就...
  • 前沿,我也是一个前端菜鸟,也是自学React,期间大大小小碰到了很多坑,现在将自己碰到的坑积累成经验分享给大家,大神勿喷,希望大家可以指点一下 React简介 React起源于Facebook的内部项目,该公司在开发自己...
  • React 入门附带demo

    2018-09-12 10:44:40
    DEMO 1 - 最简单的react渲染 代码: &lt;html&gt; &lt;head&gt; &lt;link href="css/bootstrap.min.css" rel="stylesheet"&gt; &lt;/head&gt; &lt...
  • React入门与实战之路

    2019-05-09 17:13:29
    React 是一个用于构建用户界面的 JavaScript 库,主要用于构建UI,很多人认为 React 是 MVC 中的 V(视图)。React 起源于 Facebook 的内部项目,用来架设 Instagram 的网站,并于 2013 年 5 月开源。由于 React ...
  • react - 基础入门

    2016-12-28 10:55:41
    react新手入门,适合初学者看一下。另外本人github中包含了所有的源码,麻烦在各位fork的同时,给小的赏一颗star,谢谢!
  • React入门教程

    2018-05-03 09:46:55
    1. React的起源2. React的特点2.1 虚拟DOM2.2 组件化思想2.3 JSX语法3. 创建第一个React项目3.1 环境要求3.2 创建一个可执行的React项目4. 增加一个React组件5. React数据流5.1 组件间通信:props5.2 组件内部状态:...
  • React入门指引与实战

    2018-10-16 21:20:42
    React是Facebook公司推出的前端组件化解决方案,目的在于解决前端开发中存在的各个痛点。目前,前端框架与库层出不穷,形成了异常繁荣的局面,那么Facebook为何还要重复造轮子呢?究其原因,Facebook认为现有的前端...
  • 这是2019 react入门到高级新课程 学习react,不仅能带来技术提升,同时提高开发效率和体验,更能带来好的就业机会。 本课程主要分为以下几个部分:  一,前端工程化基础?  主要学习node和npm、...
  • React基础01 入门

    2019-07-17 18:28:27
    React入门笔记。
  • React 起源于 Facebook 的内部项目,...这里分享一个react基础入门到项目实战视频,感兴趣的同学可以下载下来学习 第1章课程导学 第2章React初探 第3章React基础精讲 第4章React高级内容 第5章Redux入门 第6章Re...
1 2 3 4 5 ... 20
收藏数 11,822
精华内容 4,728
关键字:

0基础 react 入门