react基础(1)

在 react入门系列 里面,介绍了一些react的基础知识,在react基础部分,会结合手脚架工具进行更多的总结。css

关于webpack我在这里就不讲解了,有须要的小伙伴能够本身去百度一下学习资料,我这里会贴出来现成的东西供你们使用。html

关于es6的内容,在写案例的时候会有涉及,我会贴出来相应的教程,没有了解过es6的小伙伴能够去看一下。node

 

建立项目

1. 建立一个项目文件夹(我是在D盘建立了一个react文件)react

 

2. 进入react文件夹,新建两个文件package.json和webpack.config.js,新建一个src文件夹,以下所示:jquery

下面为了方便你们知道是什么文件夹下的什么文件,我都会以react/xx/xx.xx这样的方式来标明是哪一个文件或文件夹,例如上图中的package.json,我就会写成react/package.jsonwebpack

 

package.json和webpack.config.js内容以下git

 

react/package.jsones6

 

{
  "private": true,
  "entry": {},
  "dependencies": {
    "antd": "^1.1.0",
    "atool-build": "0.7.x",
    "babel-plugin-antd": "0.4.x",
    "babel-plugin-transform-runtime": "^6.8.0",
    "babel-runtime": "^6.6.1",
    "classnames": "^2.2.3",
    "es3ify-loader": "^0.2.0",
    "history": "^2.0.1",
    "isomorphic-fetch": "^2.2.1",
    "js-cookie": "^2.1.1",
    "react": "^15.3.2",
    "react-dom": "^15.0.2",
    "react-redux": "^4.4.5",
    "react-router": "^2.0.1",
    "spmhandlebars-loader": "^0.1.0"
  },
  "devDependencies": {
    "atool-test-mocha": "^0.1.4",
    "babel-eslint": "^6.0.0",
    "dora": "0.3.x",
    "dora-plugin-browser-history": "^0.1.1",
    "dora-plugin-hmr": "0.6.x",
    "dora-plugin-livereload": "0.3.x",
    "dora-plugin-proxy": "0.6.x",
    "dora-plugin-webpack": "0.6.x",
    "eslint": "^2.7.0",
    "eslint-config-airbnb": "6.x",
    "eslint-plugin-react": "4.x",
    "expect": "^1.20.1",
    "glob": "^7.0.3",
    "pre-commit": "1.x",
    "react-redux": "^4.4.5",
    "redux": "^3.5.2"
  },
  "pre-commit": [
    "lint"
  ],
  "scripts": {
    "build": "atool-build",
    "lint": "eslint --ext .js,.jsx src",
    "start": "dora -p 8001 --plugins \"webpack,hmr,proxy,livereload?enableJs=false&injectHost=127.0.0.1,browser-history?index=/src/entries/index.html\"",
    "test": "atool-test-mocha ./src/**/__tests__/*-test.js"
  }
}

 

react/webpack.config.jsgithub

 

// Learn more on how to config.
// - https://github.com/ant-tool/atool-build#配置扩展

const webpack = require('atool-build/lib/webpack');
const fs = require('fs');
const path = require('path');
const glob = require('glob');

module.exports = function(webpackConfig) {
  webpackConfig.babel.plugins.push('transform-runtime');
  webpackConfig.babel.plugins.push(['antd', {
    style: 'css',  // if true, use less
  }]);

  // Enable this if you have to support IE8.
  // webpackConfig.module.loaders.unshift({
  //   test: /\.jsx?$/,
  //   loader: 'es3ify-loader',
  // });

  // Parse all less files as css module.
  webpackConfig.module.loaders.forEach(function(loader, index) {
    if (typeof loader.test === 'function' && loader.test.toString().indexOf('\\.less$') > -1) {
      loader.test = /\.dont\.exist\.file/;
    }
    if (loader.test.toString() === '/\\.module\\.less$/') {
      loader.test = /\.less$/;
    }
  });
  
  webpackConfig.module.loaders.push({
    test: /\.handlebars$/,
    loader: 'spmhandlebars-loader'
  });

  // Load src/entries/*.js as entry automatically.
  const files = glob.sync('./src/entries/*.js');
  const newEntries = files.reduce(function(memo, file) {
    const name = path.basename(file, '.js');
    memo[name] = file;
    return memo;
  }, {});
  webpackConfig.entry = Object.assign({}, webpackConfig.entry, newEntries);

  return webpackConfig;
};

 

这里对上面两个文件不作讲解,在下面会对package.json作一些讲解。(关于webpack的一些内容不会讲不少,你们能够去ant-design学习一下,也能够本身去网上找webpack的资料学习。)web

 

3. 进入src文件夹,建立entries文件夹,在entries文件夹里新建index.html、index.css、index.js三个文件

index.html、index.css、index.js三个文件的内容以下(很简单的代码,这里暂时不作讲解,先把项目正常运行了)

 

react/src/entries/index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Demo</title>
  <link rel="stylesheet" href="index.css" />
</head>
<body>

<div id="root"></div>

<script src="common.js"></script>
<script src="index.js"></script>

</body>
</html>

react/src/entries/index.css

html, body, #root {
  height: 100%;
}
.box{
    background:red;
}

react/src/entries/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

function App() {
  return (
    <div className="box">
      demo
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById('root'));

 

4. 安装依赖

上面的文件都建立好了,返回到react文件夹下,按住shift键,同时点击鼠标右键(以下图所示)

点击“在此处打开命令窗口”,就能够看到以下图所示(注意要在react文件下)

我这里用的是cmd,你们也能够用git进行操做

 

下一步 :$ npm install,以下图所示

若是装了淘宝镜像,则用 $ cnpm install淘宝npm镜像--教程

安装不成功的就多安装几回

安装成功了,在react文件夹下,就能够看到node_modules文件夹

 

5. 运行/开发调试 项目

在react文件夹下启用cmd(或git),$ npm start,以下图所示

 

在你的浏览器访问 http://localhost:8989/ 看到下图所示的效果就成功了

 

 6. 构建

$ npm run build,以下图所示

 

这个时候,你会发现react文件夹里多了一个dist文件夹(里面是压缩后的代码)

 

 

如今项目已经建立成功了,下面就进入正题了。

首先要讲的是和 react入门 系列里面不同的一些写法和注意事项。

 

 

JSX

jsx语法和注意事项在 react入门(1) 讲过,这里再也不多讲。

 

 

组件

在react入门里面,咱们也讲了建立组件的写法(react入门1),这里再来介绍几种(包含es6的内容,你们能够去先去了解一下es6

这里我只对entries文件夹里的index.js里的内容进行修改,其余两个文件不作修改

修改完文件,若是没有看到效果,能够刷新一下http://localhost:8989/ 这个页面,尚未看到效果的,能够从新 $ npm start

案例1:

react/src/entries/index.js(index.html和index.css不变)

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import './index.css';

// 方法1
function One() {
  return (
    <div className="box">demo1</div>
  );
}

// 方法2
const Two = () => {
  return (
    <div>demo2</div>
  );
};
 

// 方法3
class Three extends Component{
    render(){
        return (
            <div>demo3</div>
        )
    }
}

// 方法4
const Four=React.createClass({
  render:function(){
    return (
      <div>
         <One />
         <Two />
         <Three />
         demo4
      </div>
    )
  }
});

ReactDOM.render(
  <Four />,
  document.getElementById('root')
)

 效果以下

分析一下

下面这张图,结合上面的效果图里用绿色勾出来的部分一块儿看

将Four组件渲染到id名为root的div里去。这个id名为root的div,在react/src/entries/index.html里能够找到,以下图所示

react入门1 有讲过具体的原理,这里再也不多说)

 

下面再来看一下引入,都是用import来引入的,以下图所示

前面两个是咱们引入下载的的依赖(react/node_modules这个文件夹里能够看到咱们下载了哪些依赖,这里不细讲),最后一个是引入css样式。

这里贴一个关于import的教程(原文地址

 

下面主要说一下组件的写法,上面我列举了四种写法,我一一来分析

方法1,这种写法我就很少说,相信你们都能看懂

 

方法2,这个是es6的箭头函数,相似方法1,只是换成了es6的写法。

更加简洁的写法以下

const Two = () => <div>demo2</div>;

贴一个箭头函数的教程帮助你们理解(原文地址

 

 

接下来看一下方法3

方法3,class是es6的内容,以下图所示,能够这么理解

Component是从react里面来的,以下图所示

 

这里咱们的render(){}是直接这么写的,而之前咱们都是写的render:function(){},这也是es6的内容。除了render(){}能够写成这样,其余的function均可以这么写,在下面的例子中你们继续看。

 

贴一个class的教程帮助你们理解(原文地址

 

 

再来看一下方法4

方法4,和咱们以前在 react入门 系列里面写的是同样的,这里再也不多说。

 

 

CSS

react入门(1)也介绍了css的写法,这里再来介绍一些不一样的写法。

 

react/src/entries文件夹里,新建一个文件index.less,以下所示

react/src/entries/index.less内容以下(less教程,这里先不讲less,不懂less的小伙伴就直接在里面写普通的css便可)

.blue{
    color:blue
}
.bg{
    background:grey
}

 案例2:

react/src/entries/index.js(index.html、index.css和index.less不变)

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import styles from './index.less'

class App extends Component {
  render(){
    return(
      <div>
        <p className='box' style={{color:'#fff'}}>轻音乐</p>
        <p className={styles.blue}>摇滚乐</p>
        <p className={styles.blue+' '+styles.bg}>抒情音乐</p>
        <p className={'box '+styles.blue}>老情歌</p>
      </div>
    )
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
)

效果以下

下面来分析一下

如上图所示,引入了一个css和一个less文件(这里styles能够自定义取名,abc什么的均可以)

 

下面来看一下css的几种写法

  •  

如上图所示,有两种写法

className='box',这个box是在index.css里的,这也是咱们以前在 react入门1 里就讲过的写法

style={{color:'#fff'}},这种写法至关因而行内样式,要注意:必须写两个花括号

如上图所示,这个styles是从index.less来的(import styles from './index.less'),这种写法要注意,须要写一个花括号,在blue前要加styles.

如上图所示,当你写多个className时,要注意中间用空格隔开

 

 

事件

react入门2 里介绍了事件的写法,这里结合es6来介绍几种写法

案例3:

react/src/entries/index.js(index.html、index.css和index.less不变)

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import './index.css'; class App extends Component { clicks(){ alert(
1) } render(){ return( <div> <button onClick={this.clicks.bind(this)}>按钮1</button> <button onClick={ ()=>alert(2) }>按钮2</button> </div> ) } } ReactDOM.render( <App />, document.getElementById('root') )

 效果以下:

分析一下

如上图所示,当点击button的时候,触发onClick事件,而后调用clicks方法。这里要注意的是,格式this.xxx.bind(this)

如上图所示,在花括号里面写的是 es6的箭头函数(箭头函数在 案例1 贴过教程了)。

 

 

props

在子组件经过this.props.xxx来获取父组件传递的信息,在 react入门(2) 讲过,这里再也不详细讲解

 

 

State

react入门3 里面介绍了state,都是在getInitialState里设置初始状态,以下

getInitialState:function(){
     return {
         val:'red'
     };
}

 es6的写法又会有所不一样,下面来看一个例子

 

案例4:

react/src/entries/index.js(index.html、index.css和index.less不变)

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import './index.css';

class App extends Component {
  constructor() {
      super();
      this.state = {
          val:123
      };
  }

  render(){
    return(
      <div>
        {this.state.val}
      </div>
    )
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('root')
)

下面来分析:

如上图所示,在设置初始值的时候,是这样写的。

 

这里说几个注意点:

1. 在constructor(){}里设置state的初始状态

这里贴一个constructor的教程(原文地址

 

 

2. 初始状态的设置,在 react入门 系列里面,都是在getInitialState里直接return的,而这里要写在this.state{}

 

3. super关键字很重要,若是要在constructor里用到this,那么咱们必需要写super(),不然会报错。值得一提的是,必须先调用super,才可使用this,不然也会报错

贴一个关于super的教程(原文地址

 

4. 和 react入门 系列里面是同样的,都是经过this.state.xx来获取状态

 

 

refs

react入门3 里也介绍了的refs的相关知识,这里再总结一下。

 

案例5:

react/src/entries/index.js(index.html、index.css和index.less不变)

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import './index.css'; class Parent extends Component { constructor() { super();
this.state = { val:321 }; } changes(){ this.setState({ val:this.refs.inputs.value }) } render(){ return( <div> <input ref="inputs" value={this.state.val} onChange={this.changes.bind(this)} /> <Child txt={this.state.val} /> </div> ) } } class Child extends Component{ render(){ return( <span> {this.props.txt} </span> ) } } ReactDOM.render( <Parent />, document.getElementById('root') )

效果以下

下面来分析一下

  • 在constructor里设置val初始值

  •  input里首先经过this.state.val获取val的值,当input值发生改变的时候,触发onChange事件,调用changes方法。这里ref属性,就至关于给input取了一个名,叫inputs

  •  在changes里,经过this.setState从新给val赋值,值为this.refs.inputs.value。this.refs.inputs就至关于获取了ref属性值为inputs的input;this.refs.inputs.value就至关于获取了这个input的value值

  • 在子组件Child里,经过this.props.txt获取父组件Parent上Child标签上txt的属性值,即为input的value值

 

 

package.json

关于package.json这里讲一下下图列表的东西都是怎么来的吧。

看到上面红色框勾出来的,这里就以react为例来说解。

"react": "^15.0.2",冒号前面是名字,冒号后面是版本号。

 

上面列表里的内容都是怎么来的呢? 

 

先将上面红色框勾出来的这一行删除(以下图所示)。

在react文件夹下启动cmd或者git:$ npm install react --save(以下图所示)

完成以后,就能够看到,列表里面又有了react这一行(版本号可能不同,以下图所示)

当有了上面红框这一行,就表示你成功了,除了这里,还能够在react/node_modules文件夹里也会找到react这个文件夹,以下图所示

 

有了react/package.json这个文件,你能够把react/node_modules文件夹删除,而后在react文件夹下启动cmd或者git:$ npm i,以下图所示

又会从新安装这些依赖,从新生成node_modules文件夹

 

关于package.json那些列表里的东西都是作什么的、怎么用,你们能够去npm或者cnpm去查一下

 

 

mock数据

在讲解ajax以前,先说一下怎么mock数据吧

react/src文件夹下新建一个mock文件夹,以下图所示

react/src/mock文件夹下,新建一个music.json文件,以下图所示

react/src/mock/music.json 文件内容以下

{
    "success":true,
    "data":[
        {
            "id":1,
            "music":"rock"
        },
        {
            "id":2,
            "music":"pop"
        },
        {
            "id":3,
            "music":"classical"
        }
    ]
}

 

在react文件夹下新建proxy.config.js,以下图所示

react/proxy.config.js 内容以下

module.exports = {
  '/users': function(req, res) {
      res.json({
        success: true,
        data: [
          {
            "id":1,
            "username":"sam"
          },
          {
            "id":2,
            "username":"amy"
          },
          {
            "id":3,
            "username":"kim"
          }
        ],
      });
  },

  'GET /music': './src/mock/music.json'
};

下面来分析

在这里我就写了这两种mock数据的方式,更多的方法戳这里去看:规则定义

 

写到这里,我顺带粘贴一下个人文件目录

 

 

ajax

关于ajax,咱们须要借助别的库、插件、依赖,例如像jquery、zepto、fetch、superagent等等,能够去npm搜索一下ajax挑选本身喜欢的一种。

这里咱们用的是isomorphic-fetchisomorphic-fetch教程),在package.json里能够找到,以下图所示

react/package.json

 

 

案例6:

react/src/entries/index.js(index.html、index.css和index.less不变)

import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import fetch from 'isomorphic-fetch';

class Parent extends Component {
  componentWillMount(){
    var self = this;
    fetch('/users')
      .then(function(response) {
          if (response.status >= 400) {
              console.log("Bad response from server");
          }
          return response.json();
      })
      .then(function(data) {
          self.setState({users:data.data})
      });
  }

  constructor() {
      super();
      this.state = {
          users:[]
      };
  }

  render(){
    return(
      <ul>
        {
          this.state.users.map(function(user, index){
            return (
              <li key={index}>{user.username}</li>
            )
          })
        }
      </ul>
    )
  }
}

ReactDOM.render(
  <Parent />,
  document.getElementById('root')
)

 在react文件夹下启动服务器:$ npm start,在浏览器打开http://localhost:8989/,效果以下

下面来分析一下

componentWillMount,组件即将加载,这时候能够用ajax获取初始化页面须要用到的数据。

 

下面来分析上面的map循环(在 react入门2 里有讲过map循环),先写一个for循环作对比

var arr = [1,2,3,4];
for(var i=0;i<arr.length;i++){
   console.log(arr[i])
}

 

固然除了isomorphic-fetch,还有其余实现ajax的方法,这里就不讲了。

 

此次就讲解这么多,有疑问的地方欢迎你们给我留言~~~

相关文章
相关标签/搜索