资讯

精准传达 • 有效沟通

从品牌网站建设到网络营销策划,从策略到执行的一站式服务

70react_环境搭建_组件状态

 

目前成都创新互联公司已为近1000家的企业提供了网站建设、域名、虚拟主机、网站托管、服务器托管、企业网站设计、铜梁网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。

 

 

目录

React项目:...1

win下开发环境的搭建:...1

简介:...5

例,测试程序:...7

例,组件状态:...9

例,复杂例子:...11

 

 

 

React项目:

 

win下开发环境的搭建:

 

react-mobx-starter-master.zip   #解压此文件到指定位置,该位置即为项目根目录

 

$ npm install   #或$npm i,会按照package.json的配置,安装依赖模块,生成node_modules目录(安装所有依赖的模块)

……

added 1212 packages in 135.079s

 

 

配置文件说明:

package.json文件:

npm init后产生的文件,记录项目信息,项目依赖;

需要修改name、version、description、repository、author、license,改好后可开始开发;

{

  "name": "react-mobx-starter",

  "version": "1.0.0",

  "description": "react mobx starter",

  "main": "index.js",

  "scripts": {   #项目管理,start指定启动webpack的dev server,build使用webpack构建打包

    "test": "test",

    "start": "webpack-dev-server --config webpack.config.dev.js --hot --inline",

    "build": "webpack -p --config webpack.config.prod.js"

  },

  "repository": {},   #版本管理,如有用type和url定义,"type": "git","url":"……"

  "author": "magedu",

  "license": "MIT",

  "devDependencies": {   #开发时依赖

    "babel-core": "^6.24.1",   #babel转译,因为开发用了很多ES6语法,从6.X开始babel拆分成很多插件,需要什么引入什么,babel-core为核心

    "babel-jest": "^19.0.0",

    "babel-loader": "^6.4.1",   #webpack的loader,webpack是基于loader的

    "babel-plugin-transform-decorators-legacy": "^1.3.4",   #转换装饰器用

    "babel-plugin-transform-runtime": "^6.23.0",

    "babel-preset-env": "^1.4.0",   #babel-preset-X,预设的转换插件

    "babel-preset-react": "^6.24.1",

    "babel-preset-stage-0": "^6.24.1",

    "css-loader": "^0.28.0",   #css相关,包括css-loader、less、less-loader、style-loader

    "html-webpack-plugin": "^2.28.0",

    "jest": "^19.0.2",

    "less": "^2.7.2",

    "less-loader": "^4.0.3",

    "react-hot-loader": "^3.0.0-beta.6",   #热加载插件,在改动保存后,直接在页面上就能反馈,不需要手动刷新

    "source-map": "^0.5.6",   #文件打包,js会合并或压缩,没法调试,用它来看js源文件是什么,source-map-loader也需要webpack的loader

    "source-map-loader": "^0.2.1",

    "style-loader": "^0.16.1",

    "uglify-js": "^2.8.22",

    "webpack": "^2.4.1",   #打包工具

    "webpack-dev-server": "^2.4.2"   #启动一个开发的server

  },

  "dependencies": {   #运行时依赖

    "antd": "^2.9.1",   #基于react实现,蚂蚁金服开源的react的UI库,做中后台管理非常方便

    "axios": "^0.16.1",   #异步请求支持

    "babel-polyfill": "^6.23.0",   #解决浏览器api不支持的问题,可抹平差异化

    "babel-runtime": "^6.23.0",

    "mobx": "^3.1.9",   #状态管理库,透明化

    "mobx-react": "^4.1.8",

    "mobx-react-devtools": "^4.2.11",

    "prop-types": "^15.5.8",

    "react": "^15.5.4",   #react开发的主框架,reaact-dom支持DOM,react-router支持路由,react-router-dom,DOM绑定路由;react和mobx是强强联合

    "react-dom": "^15.5.4",

    "react-router": "^4.1.1",

    "react-router-dom": "^4.1.1"

  }

}

 

.babelrc文件:

babel转译的配置文件,按官网给的配置:

{

  "presets": [

    "react",

    "env",

    "stage-0"

  ],

  "plugins": ["transform-decorators-legacy", "transform-runtime"]

}

 

webpack.config.dev.js文件:

这是一个符合commonjs的模块,webpack配置;

const path = require('path');

const webpack = require('webpack');

module.exports = {   #导出

    devtool: 'source-map',   #导出devtools是source-map

    entry: {   #描述入口,entry如果是一个字符串,定义就是入口文件;如果是一个数组,里面包含入口文件,另一个参数可用来配置一个服务器;这里配置的是热加载插件,可自动刷新

        'app': [

            'react-hot-loader/patch',

            './src/index'

        ]

    },

    output: {   #输出,输出目录是__dirname+'dist',文件名是bundle.js

        path: path.join(__dirname, 'dist'),

        filename: 'bundle.js',

        publicPath: '/assets/'

    },

    resolve: {   #指定解析什么文件类型,此处设置对js文件解析

        extensions: ['.js']

    },

    module: {   #模块

        rules: [   #对.js结尾但不在node_modules目录的文件使用热加载loader和转译babel-loader

            {

                test: /\.js$/,

                exclude: /node_modules/,   #打包排除目录,重要,一定要有,否则编译就把这个目录下所有文件拿出来,超大无比

                use: [

                    { loader: 'react-hot-loader/webpack' },

                    { loader: 'babel-loader' }

                ]

            },

            {

                test: /\.less$/,

                use: [

                    { loader: "style-loader" },

                    { loader: "css-loader" },

                    { loader: "less-loader" }

                ]

            }

        ]

    },

    plugins: [   #webpack的插件

        new webpack.optimize.OccurrenceOrderPlugin(true),

        new webpack.HotModuleReplacementPlugin(),

        new webpack.DefinePlugin({'process.env': {NODE_ENV: JSON.stringify('development')}})

    ],

    devServer: {   #开发用server,启动端口3000,支持热加载;proxy,指定访问/api开头的路径都代理到http://127.0.0.1:8080

        compress: true,

        port: 3000,

        publicPath: '/assets/',

        hot: true,

        inline: true,

        historyApiFallback: true,

        stats: {

            chunks: false

        },

        proxy: {

            '/api': {

                target: 'http://127.0.0.1:8080',

                changeOrigin: true

            }

        }

    }

};

 

jsconfig.json文件:

vscode的本地配置文件,覆盖当前配置;

{

    "compilerOptions": {

        "target": "ES6",

        "module": "commonjs",

        "experimentalDecorators": true

    }

}

 

 

$ npm start   #启动项目,在项目根目录下

70react_环境搭建_组件状态

 

http://127.0.0.1:3000/   #启动成功,访问

“查看网页源代码”   #下载到用户本地执行

F12,Network,都是动态生成的;

VS中打开react-mobx-starter-master/index.html,修改

段,保存,重新打开网页,网页内容会有变化;

VS中查看reac-mobx-starter-master/src/index.js;

 

 

简介:

React是facebook开发并开源(2013年开源)的前端框架;

11年他们团队在市面上没找到合适的MVC框架,就自己写了一个js框架,用在大名鼎鼎的Instagram图片分享社区网络;

React解决的是前端MVC框架中的View视图层的问题;

 

Virtual DOM:

document object model,文档对象模型;

将网页内所有内容映射到一棵树型结构的层级对象模型上,browser提供对DOM的支持,用户可用脚本调用DOM API来动态的修改DOM结点,从而达到修改网页的目的,这种修改在browser中完成,browser会根据DOM的改变重绘改变的DOM结点部分;

修改DOM重新渲染代价太高,前端框架为了提高效率,尽量减少DOM的重绘,提出了virtual dom,所有的修改都是在当前virtual dom上完成的,通过比较算法,找出browser DOM之间的差异,使用这个差异操作DOM,browser只需要渲染这部分变化就行;

React实现了DOM diff算法,可高效比对virtual DOM和DOM的差异(类似事务,一块提交);

virtual DOM实质是内存中的数据结构;

 

支持JSX语法:

JSX,是一种javascript和xml混写的语法,是javascript的扩展;不用函数调用,就可知道结构;

JSX语法是XML,要求所有元素必须闭合,如
不能写成

JSX规范:

首字母小写就是html标记,首字母大写就是组件;

要求严格的html标记,要求所有标签必须闭合,如
,/前留一空格;

单行省略小括号,多行使用小括号;

元素有嵌套建议多行,注意缩进;

jsx表达式,使用{}括起来,如果大括号内使用了引号,会当作字符串处理,如

{'2>1?true:false'}
,里面的表达式就为字符串了;

React.render(

 

   

     

content

   

 

,

 document.getElementById('example')

);

 

state组件状态:

每一个React组件都有一个状态变量(各是各的),它是一个javascript对象,可为它定义属性来保存值,如果状态变化了,会触发UI的重新渲染;

state是组件自己内部使用的,是组件私有的属性;

 

组件是封装的最小单位;

jsx内只允许表达式,三目运算符即为表达式(换为if...else即为语句);

getElementById,通常用id找,也有用name找;

render()内,一般认为state是变化过的,建议不要再对state作变化;

setTimeout()和setInterval()是异步处理的,是在render()之后改的;

state对象中,属性的值可以是字符串、对象、数组等,只要这个值发生了变化就可以;

组件间的通信用props;

 

 

例,测试程序:

src/index.js

import React from 'react';   //导入React模块,主框架

import ReactDom from 'react-dom';   //导入ReactDom模块

 

class Root extends React.Component {   //方1,推荐用jsx语法,组件类定义,从React.Component类上继承,这个类生成JSXElement对象,即react元素;叫react组件,或react元素,或jsx元素

 render() {   //渲染函数,返回组件中渲染的内容,只能返回唯一一个顶级元素,重要

   return

hello magedu
   //必须返回一个顶级元素,若为
aa

则报错,JSX语法是XML,要求所有元素必须闭合

  }

}

 

// class Root extends React.Component {   //方2

//   render() {

//     return React.createElement('div', null, 'welcome to magedu.');

//   }

// }

 

 

ReactDom.render(,document.getElementById('root'));   //第一个参数是JSXElement对象,第二个参数document.getElementById('root')是DOM的Element元素,将React元素添加到Dom的Element元素中并渲染,此处root要与index.html的

对应

// ReactDom.render(React.createElement(Root), document.getElementById('root'));   //方2,还可使用React.createElement创建react元素,第一参数是React组件或一个HTML的标签名称(如div、span)

 

src/index.js保存后,会自动编译,并重新装载刷新browser端界面;

 

增加一个子元素:

import React from 'react';

import ReactDom from 'react-dom';

 

class SubEle extends React.Component {

 render() {

   return

sub content
;

   // return

{1 + 2}
;   //V

   // return

{1<2?'true':'false'}
;   //V

   // return

{'1<2?true:false'}
;   //X,表格式显示为字符串

   // return

{1<2?true:false}
;   //X,true和false去掉引号,browser将不会显示

  }

}

 

class Root extends React.Component {

 render() {

   return (

     

   //首字母小写是html标记

       

welcome magedu.com

       

          //首字母大写是组件

     

    );

  }

}

 

ReactDom.render(,document.getElementById('root'));

 

http://127.0.0.1:3000/api/index.js

504 Gateway Timeout 

注:可用于做代理事情;

 

 

例,组件状态:

import React from 'react';

import ReactDom from 'react-dom';

 

class SubEle extends React.Component {

 render() {

   return

sub content
;

  }

}

 

class Root extends React.Component {

 state = {   //内部私有,此类之外是不允许访问的,这种方式不好

   p1:'magedu',

   p2:'.com'

  };

 

 dealsth() {

   this.setState({p1:'www.magedu'});

  }

 

 render() {

   // this.state.p1 = 'www.magedu';   //V,可以更新

   // this.setState({p1:'www.magedu'});   //X,不可以对还在更新中的state使用setState,browser的Console上有警告Warning

   setTimeout(()=> this.setState({p1:'magedu',p2:'.net'}),5000);   //V,可用延时函数操作,5s后页面自动刷新;this.setState({p1:'magedu'})并不会把state对象的所有属性覆盖掉,只是改了对应p1属性的值

   // this.dealsth();   //X,通过方法操作也不可以

 

   return (

     

       

welcome to{this.state.p1}{this.state.p2}

       

       

     

    );

  }

}

 

ReactDom.render(,document.getElementById('root'));

 

 

this.setState({p1:'www.magedu'});   //X,表现如下

70react_环境搭建_组件状态

Warning: setState(...): Cannot update during an existing state transition (such as within `render` or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to `componentWillMount`.

 

每5s会重绘;

 

 

例,复杂例子:

传统的html编程方式:

{/*

 

   

 

 

   

      click me,it will be trigger a event,and alert window

   

 

*/}

注:

head与http的响应头没关系,head是响应头中body部分的头,head中的