手挽手带你学React入门第一期,带你熟悉React的语法规则,消除对JSX的恐惧感,因为如今开发中都是使用ES6语法开发React,因此此次也使用ES6的模式进行教学,若是你们对ES6不熟悉的话,先去看看class相关内容吧,这里我也慢慢带你们一步一步学会React。javascript
视频你们移步个人我的博客:www.henrongyi.top,掘金放不上来呢html
React是Facebook的一群变态们开发的一个特别牛X的框架。它其实是一个虚拟DOM,而后在这个DOM中,要用什么组件就能飞速加载进来,不要的时候,立刻给删咯(实际上就是个前端框架,都是这么个意思,VUE,NG都是,只不过他们的数据流向不一样而已,React区别就在于,单向数据流。),React 扮演着 MVC 结构中 V 的角色,后面我会用到基于FLUX架构的Redux让咱们的整个项目变成MVC架构。总之,React也是hie牛X的。前端
React是一款很是牛X的前端框架,它的衍生物React-Native可让你开发接近原生体验的NativeApp,它适合的范围至关普遍,前端,后端,手机端,都有很好的兼容性。总而言之,hie牛X。vue
如今的开发中React项目实际上都是使用ES6语法来编写,而且,咱们如今有不少成熟的脚手架可使用(create-react-app,dva等),不过国际惯例,咱们要从最基础的用法开始编写。咱们采用ES6写法来进行教学,同时使用webpack工具,这里会用到不少相关配置,你们能够在这个过程当中体验ES6的精妙。java
配置基础webpack环境react
这里你们能够不去深刻理解,先跟着我一步一步配置出来webpack
开始以前,你们能够去官网:reactjs.org/ 下载最新的React(当前版本v16.7.0) 中文地址:react.docschina.org/git
因为咱们不使用脚手架,因此咱们须要先建立咱们本身的webpack包,第一步es6
mkdir helloReact
cd helloReact
复制代码
首先你们命令行输入github
webpack v
复制代码
若是正常出现版本号 而且是 3.6.0版本,那么咱们就能够按照教程继续走下去了 若是没有的话 那么咱们就须要命令行继续
cnpm i webpack@3.6.0 -S -g
复制代码
到这里应该能够正常使用webpack了
接下来 咱们命令行输入
npm init -y // 这其实是 初始化一个项目 而且所有默认 固然若是你想看看里面有啥的话 就把-y拿掉就行了
npm i //这里是把webpack依赖安装到本包内部
npm i webpack-dev-server@2.11.1 --save-dev //安装本地运行服务器
npm i webpack-cli --save-dev //依赖脚手架
复制代码
运行完成之后,咱们会获得一个package.json文件 打开看看
{
"dependencies": {
"webpack": "^3.6.0" //依赖包和版本
},
"name": "helloreact", //项目名
"version": "1.0.0", // 版本号
"main": "index.js", //入口文件
"scripts": { //npm run 加这里面的key就能够快速执行命令行
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "", // 做者
"license": "ISC",
"description": "" //简介
}
复制代码
这里面其实是咱们项目的一些基础信息
咱们须要本身配置webpack和babel 这里咱们须要建立两个文件 这里面咱们要设置入口文件,输出文件,babel,webpackServer等等,这里不作太详细的介绍 你们能够直接复制代码,后面可能会开专门的webpack视频课程。 小小的介绍一下这些都是干什么用的 babel-core 调用Babel的API进行转码 babel-loader babel-preset-es2015 用于解析 ES6 babel-preset-react 用于解析 JSX babel-preset-stage-0 用于解析 ES7 提案 命令行输入
npm install --save-dev babel-core babel-loader@7.1.5 babel-preset-es2015 babel-preset-react babel-preset-stage-0
复制代码
接下来咱们在helloReact 文件夹中建立 webpack.config.js 文件
// webpack.config.js 直接复制便可
const path = require("path");
module.exports = {
/*入口*/
entry: path.join(__dirname, 'src/index.js'),
/*输出到dist文件夹,输出文件名字为bundle.js*/
output: {
path: path.join(__dirname, './dist'),
filename: 'bundle.js'
},
/*src文件夹下面的以.js结尾的文件,要使用babel解析*/
/*cacheDirectory是用来缓存编译结果,下次编译加速*/
module: {
rules: [{
test: /\.js$/,
use: ['babel-loader?cacheDirectory=true'],
include: path.join(__dirname, 'src')
}]
},
plugins : [],
devServer : {
disableHostCheck: true,
inline: true,
port:9527,
contentBase: path.join(__dirname, "/"),
}
}
复制代码
接下来咱们在helloReact 文件夹中建立 .babelrc 文件
{
"presets": [
"es2015",
"react",
"stage-0"
],
"plugins": []
}
复制代码
而后咱们在package.json文件的script中添加
//package.json
{
"dependencies": {
"webpack": "^3.6.0"
},
"name": "helloreact",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"server": "webpack-dev-server",
"build": "webpack",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"description": "",
"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^2.11.1"
}
}
复制代码
这些配置完了,咱们就在helloReact mkdir src 而且在src中建立 index.js文件 在 根路径 helloReact下建立 index.html 由于这里咱们要用到 react了 因此须要命令行安装一下 react
cnpm install --save react react-dom
复制代码
html文件以下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app"></div>
</body>
<script src="bundle.js"></script>
</html>
复制代码
js 文件以下
import React from 'react'; //es6 引入react
import ReactDom from 'react-dom'; //es6 引入reactReacrDom
ReactDom.render( //ReactDom渲染<div>hello React</div> 这个html标签 到 id='app'这个标签下
<div>Hello React!</div>, document.getElementById('app'));
复制代码
一切都写完了 咱们运行服务 npm run server 来看一眼
若是你看到屏幕显示出 Hello React! 那么恭喜你 环境配置完了 我们能够开始学习 React 了
若是你配置了半天还没配置成功
到个人github下载代码吧。。。github.com/piexlmax/he…
React的Hello World
咱们看到上面的代码
import React from 'react'; //es6 引入react
import ReactDom from 'react-dom'; //es6 引入reactReacrDom
ReactDom.render( //ReactDom渲染<div>hello React</div> 这个html标签 到 id='app'这个标签下
<div>Hello React!</div>, document.getElementById('app'));
复制代码
这是一个简单的渲染 是否是根本看不到 React的组件化模式呢?
因此这里 咱们须要写一个根部组件,之后的组件都放跟组件里面,这个JS就理所固然成了一个入口文件了
这里 咱们在 src下面建立一个app.js文件
app.js
import React, {Component} from 'react';
// 这里咱们引入 react 和 react的Component
// 建立 Hello 这个class(class属于ES6内容) 而后继承 Component 咱们就成功地建立了一个 react组件
export default class App extends Component {
render() {
return (
<div> Hello,World! </div>
)
}
}
复制代码
index.js 咱们须要改写为这样
import React from 'react';
import ReactDom from 'react-dom';
import App from './app.js' //引入咱们的根组件App
ReactDom.render( //把App 渲染到 id=app的dom中
<App/>, document.getElementById('app'));
复制代码
到这里 咱们已经实现了一个真正意义上的Hello World了!
开始玩React了,那就必需要用到jsx语法,什么是jsx呢?
JSX是一种JavaScript的语法扩展。JSX与模板语言类似,但它具备JavaScript的所有功能。JSX会被编译为React.createElement()方法调用,将返回名为“React elements”的普通JavaScript对象。
上面代码里咱们看到 咱们的html其实是在js中的render函数中书写的,是一个React扩展,容许咱们编写看起来像 HTML的JavaScript 。
切记 自定义组件必定要大写字母开头 return加括号 而且左括号要和return在同一行 只能return一个标签,其他内容都要在这个标签内部
export default class App extends Component {
render() {
return (
<div> Hello,World! </div>
)
}
}
复制代码
像是这样一段代码,实际上咱们真正使用的时候,已经通过了一次编译,编译事后它长这样。
export default class App extends React.Component {
render() {
return (
React.createElement(
'div',
'Hello,World!'
)
);
}
}
复制代码
下面的这一段代码是否是就不容易理解了?这其实是js能够帮咱们去书写dom的代码。 在React中JSX你能够理解为咱们能够在js中写HTML代码了 更通俗一点
export default class App extends Component {
// 方法 生命周期 state 等
render() {
return (
// HTML模板
)
}
}
复制代码
state
咱们以前学过VUE,VUE中每一个组件的数据存在本身的data中,那么在React中,数据存在哪里呢?没错状态state中。 因为咱们这里用的是ES6的class 因此 咱们子类constructor中必须先调用super才能引用this。 因此咱们这里应该这么写state
export default class App extends Component {
constructor(){
super()
this.state={
hello:"hello World"
}
}
render() {
return (
<div> {this.state.hello} </div>
)
}
}
复制代码
这里咱们能够看出,咱们想要在render中使用js 就须要用一个{} 这里面的内容一样能够书写简单的js表达式。
rander函数中使用state和JS表达式
export default class App extends Component {
constructor(){
super()
this.state={
hello:"hello World"
}
}
render() {
return (
<div> <ul> <li>展现state中的数据:{this.state.hello}</li> <li>三元,短路等,这里用三元示例{this.state.hello?"存在hello":"不存在hello"}</li> <li>简单计算{1+1}</li> <li>JS表达式{Math.floor(Math.random()*10)}</li> </ul> </div>
)
}
}
复制代码
方法的声明以及修改state
声名方法咱们有两种模式,一种是直接书写 方法名(参数){代码段}模式,这样的模式在调用的时候须要手动bind(this) 还有一种就是使用es6的箭头函数,让其this指向自身
修改state数据须要调用 this.setState()方法 内部接收一个对象 要修改哪一个key 就在对象内部填写这个key,而且后面的值就是你要修改的内容,若是,key在state中不存在,则会在state中增长这个key
export default class App extends Component {
constructor(){
super()
this.state={
hello:"hello World"
}
}
bye(){
this.setState({
hello:"bye world"
})
}
byebye=()=>{
this.setState({
helloo:"bye world"
})
}
render() {
return (
<div> <ul> <li>非箭头函数:{this.state.hello}</li> <li>箭头函数:{this.state.helloo}</li> </ul> <button onClick={this.bye.bind(this)}>无箭头</button> {/* 这里使用bind来绑定this 若是传参的话this.bye.bind(this,参数1,参数2) */} <button onClick={()=>{this.byebye()}}>箭头函数</button> {/* 这里是箭头函数的默认属性来搞定了this问题 若是传参的话()=>{this.byebye(参数1,参数2)*/}} </div>
)
}
}
复制代码
这里须要注意,只有触发了state的变化,才会致使组件的从新渲染
你们在vue中使用v-for 就可以完成循环生成组件这样的操做了,在react中咱们应该怎么作呢?
循环语句 咱们说过 jsx 里面是能够自由自在地使用js的 通常状况下咱们使用map循环
在循环的时候,每个return出来的标签都须要添加 key={键值} “键值”是建立元素数组时须要包含的特殊字符串属性。键值能够帮助React识别哪些元素被更改,添加或删除。所以你应当给数组中的每个元素赋予一个肯定的标识
export default class App extends Component {
constructor(){
super()
this.state={
arr:[{text:"qm"},{text:"奇淼"},{text:"大帅逼"}]
}
}
render() {
return (
<div> {/* 咱们说过 jsx 里面是能够自由自在地使用js的 这里咱们来玩一个循环生成li */} <ul> {this.state.arr.map((item,key)=>{ return(<li key={key}>{item.text}</li>) })} </ul> </div>
)
}
}
复制代码
判断语句 判断语句咱们通常使用短路表达式 三元表达式来展现咱们想要展现的内容,可是若是须要复杂的条件判断,那么咱们最好是写一个自执行函数,而后再函数体内你就能够随心所欲了,记住必定要return你想要获得的dom标签。
export default class App extends Component {
constructor(){
super()
this.state={
arr:[{text:"qm"},{text:"奇淼"},{text:"大帅逼"}]
}
}
render() {
return (
<div> {/*简单的三元和短路实例*/} {this.state.arr.length==3?<div>我是三元判断的三个</div>:<div>我是三元判断的不是三个</div>} {this.state.arr.length==3&&<div>我是短路判断的三个</div>} {/* 咱们说过 jsx 内部支持简单的表达式 若是咱们使用 if条件句的话 会致使报错*/} {/* if(this.state.arr.length==3){ return(<div>有三个</div>) } */} {/* 咱们说过 jsx 这已是js代码段而不是简单语句了,咱们简单判断可使用三元或者短路表达式来进行,可是复杂一点的,咱们可使用以下方法*/} {(()=>{ if(this.state.arr.length==3){ return(<div>数组有三个元素</div>) }else{ return(<div>数组有不是三个元素</div>) } })()} </div>
)
}
}
复制代码
循环判断嵌套 有些时候咱们须要根据特定条件去循环,而后渲染出筛选事后的数据,这时候就须要循环和判断嵌套使用了,其实也至关简单,咱们的循环其实是一个简单的js表达式,内部的function中能够随意书写js,记得return就行了
export default class App extends Component {
constructor(){
super()
this.state={
arr:[{text:"qm"},{text:"奇淼"},{text:"大帅逼"}]
}
}
render() {
return (
<div> {this.state.arr.map((item,key)=>{ if(key%2==0){ return(<div key={key}>我是能够余2的{item.text}</div>) }else{ return(<div key={key}>我是不能余2的{item.text}</div>) } })} </div>
)
}
}
复制代码
有些时候咱们不得不去操做DOM,那这时候 咱们须要用到 ref 属性
React支持一个能够附加到任何组件的特殊属性ref。ref属性能够是一个字符串或一个回调函数。当ref属性是一个回调函数时,函数接收底层DOM元素或类实例(取决于元素的类型)做为参数。这使你能够直接访问DOM元素或组件实例。
另外这里应该注意 不要过分使用 Refs。
export default class App extends Component {
constructor(){
super()
this.state={
arr:[{text:"qm"},{text:"奇淼"},{text:"大帅逼"}]
}
}
render() {
return (
<div> {this.state.arr.map((item,key)=>{ if(key%2==0){ return(<div ref="link" key={key}>我是能够余2的{item.text}</div>) {/* 这样咱们能够经过 this.refs.link 获取到这个dom 而且操做dom了 */} }else{ return(<div key={key}>我是不能余2的{item.text}</div>) } })} </div>
)
}
}
复制代码
到这里咱们已经学会了React的基本组件内部的操做了,React相对于Vue来讲更加灵活,可是惟一的缺点是数据流是单向的,必须经过setState来修改,对于处理表单来讲会有些麻烦,不过有些UI框架,插件帮咱们处理了这些大麻烦。写写玩玩吧React仍是比较简单的。