从一个例子中体会React的基本面

【起初的准备工作】


npm init
npm install --save react react-dom
npm install --save-dev html-webpack-plugin webpack webpack-dev-server babel-core babel-loader babel-preset-react

  • react react-dom是有关react
  • html-webpack-plugin:用来把源文件,比如把src/index.html复制到dest/中的index.html中,并引用经webpack捆绑后的js文件
  • webpack:不多说
  • webpack-dev-server:搭建一个本地服务器
  • babel-core, babel-loader用来把jsx转换成js文件
  • babel-preset-react:在babel中设置react

【文件结构】


app/
.....index.html
.....index.js
.babelrc
package.json
webpack.config.js

  • .babelrc:在其中设置react
  • webpack.config.js:webpack的配置文件

【使用webpack需求与实现】

  • 用webpack把js文件捆绑到根目录下的dist文件夹下的index_bundle.js
  • 复制app/index.html文件,在根目录下的dist文件夹下生成一个index.html文件,并引用index_bundle.js
  • 运行npm run 某某名称,来执行webpack -p命令

也就是:

app/
.....index.html
.....index.js
dist/
.....index.html
.....index_bundle.js
.babelrc
package.json
webpack.config.js


webpack.config.js, 这个webpack的配置文件中大致包括:接受源文件、放到目标文件夹、使用babel把jsx文件转换成js文件、对源文件进行复制,等等。


var HtmlWebpackPlugin = require('html-webpack-plugin');
var HtmlWebpackPluginConfig = new HtmlWebpackPlugin({
template: __dirname + '/app/index.html',
filename: 'index.html',
inject: 'body'
})

module.exports = {
entry: [
'./app/index.js'
],
output: {
path: __dirname + '/dist',
filename: "index_bundle.js"
},
module: {
loaders: [
{test: /.js$/, exclude: /node_modules/, loader: "babel-loader"}
]
},
plugins: [
HtmlWebpackPluginConfig
]
}

  • HtmlWebpackPlugin:用来文件复制,template表示源文件的具体地址, filename表示复制到目标文件夹后的文件名称, inject:'body'表示把经webpack生成的index_bundle.js文件被引用到body中
  • module中的loaders使用babel进行jsx到js文件的转换, test使用正则表达式对需要被转换的文件进行限定,exclude是babel在进行转换时需要排除的源文件夹
  • entry:babel在这里找入口源文件
  • output:经babel转换后的文件保存位置
  • plugins:使用HtmlWebpackPlugin,用来文件复制

.babelrc文件中,babel需要对react的jsx进行转换,配置如下:


{
"presets": [
"react"
]
}


最后一点,如何运行npm run 某某名称,来执行webpack -p命令呢?


需要在package.json中配置


{
"name": "reactjspracticeswithtyler",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"production": "webpack -p"
},
"author": "",
"license": "ISC",
"dependencies": {
"react": "^15.1.0",
"react-dom": "^15.1.0"
},
"devDependencies": {
"babel-core": "^6.9.0",
"babel-loader": "^6.2.4",
"babel-preset-react": "^6.5.0",
"bootstrap": "^3.3.6",
"html-webpack-plugin": "^2.17.0",
"webpack": "^1.13.1",
"webpack-dev-server": "^1.14.1"
}
}

以上,在scripts下的配置,意思是说运行npm run 某某名称,实际是执行webpack -p命令。


【第一个React组件】


app/index.html


<!doctype html>



Untitled Document



以上,我们即将要把React组件插入到id为app的div中。


app/index.js,在这里创建组件


var React = require('react');
var ReactDOM = require('react-dom');

//1、生产Component
//这里是jsx的语法
var HelloWorld = React.createClass({
render: function(){
//console.log(this.props);
return (

Hello {this.props.name}

)
}
});

//2、渲染出来
ReactDOM.render(
,
document.getElementById('app')
);

  • React.createClass创建组件, render必不可少否则报错,return返回的语法就是jsx语法,将来需要用Babel转换成js文件
  • 组件的名称,像这里的HelloWord,第一个字母一般大写
  • ReactDOM.Render用来把组件渲染到DOM上
  • 组件的表现形式就像html元素,比如这里的<HelloWorld name="darren" anySortData={29}/>,这里,对name和anySortData的赋值,实际上会赋值到组件的this.props.name和this.props.anySortData中

运行npm run production,因为我们在package.json中的scripts下已经有了设置,相当于运行webpack -p命令,接下来会根据webpack.config.js中的设置,找到app/index.js,使用babel把index.js中的jsx部分转换成js保存到dist/index_bundle.js中;这时候,html-webpack-plugin开始工作了,把app/index.html复制保存到dist/index.html中,并把index_bundle.js中注入到dist/index.html的body中。


还有一个问题需要解决,当在浏览器中输入localhost:8080的时候,能浏览到网页。怎么做呢?


需要在package.json中进行设置,在scripts中进行如下设置


{
"name": "reactjspracticeswithtyler",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"production": "webpack -p",
"start":"webpack-dev-server"
},
"author": "",
"license": "ISC",
"dependencies": {
"react": "^15.1.0",
"react-dom": "^15.1.0"
},
"devDependencies": {
"babel-core": "^6.9.0",
"babel-loader": "^6.2.4",
"babel-preset-react": "^6.5.0",
"bootstrap": "^3.3.6",
"html-webpack-plugin": "^2.17.0",
"webpack": "^1.13.1",
"webpack-dev-server": "^1.14.1"
}
}

以上,在scripts下添加了"start":"webpack-dev-server"部分。


运行npm run start命令,在浏览器中输入localhost:8080就可以看到内容。


【组件嵌套】


var USER_DATA = {
name: 'darren',
username: 'DarrenActive',
image: 'https://avatars0.githubusercontent.com/u/2933430?v=38s=460'
};

var React = require('react');
var ReactDOM = require('react-dom');

//被嵌套组件
var ProfilePic = React.createClass({
render: function(){
return <img src={this.props.imageUrl} style={{height: 100, width: 100}} />
}
})

//被嵌套组件
var ProfileLink = React.createClass({
render: function(){
return (


<a href={'https://www.github.com/' + this.props.username}>
{this.props.username}


)
}
});

//被嵌套组件
var ProfileName = React.createClass({
render: function(){
return (

{this.props.name}

)
}
})

//嵌套组件
var Avatar = React.createClass({
render: function(){
return (






)
}
})

ReactDOM.render(
,
document.getElementById('app')
);

嵌套组件和被嵌套组件的关系就像河流的上下游,这里的嵌套组件Avatar在河流的上游,这里的被嵌套组件ProfileName在河流的下游,Avatar组件通过user来获取外界的赋值,user接受到值后往下游的ProfileName流动,user中的值再赋值给ProfileName的name,依次类推。


所以,React的数据流动是单向的,由外向内的流动。


【组件元素嵌套】


组件嵌套和组件元素嵌套不一样。组件嵌套大致是:

var Room = React.createClass({
render: function(){
return (




)
}
});


组件元素嵌套大致是:

var Room = React.createClass({
render: function(){
return (




posted @ 2016-05-30 13:57  Darren Ji  阅读(1065)  评论(0)    收藏  举报

我的公众号:新语新世界,欢迎关注。