react-cli安装及目录介绍

3,231 阅读6分钟

1、安装

cnpm i create-react-app@3.2.0 -g
create-react-app -V 
create-react-app 名_字	//下载时间比较长 
cnpm(npm) run start //启动

2、目录介绍

node_modules //第三方依赖的包
public    //资源目录
    favicon.ico    //左上角的图标
    index.html      //项目首页模板
    manifast.json    //定义 app 的图标 网址 主题颜色等
       robots.txt        //robots协议  User-agent: * 允许所有 #注释协议网址

src      //项目所有的源代码
    index.js        //整个程序的入口 (react 的理念 all in js)
    index.css        //初始化样式,存放于网站根目
    App.js        //项目通用部分
    App.test.js       //自动化测试文件
    App.css         //项目的样式
    logo.svg        //首页 logo
    serviceWorker.js   //将网页存储在浏览器内 如果突然断网了 可以继续访问该网页 
.gitignore        //设置禁止传到 git 文件
package.json        //模块清单 和项目介绍 ( 命令行 命令 ) 等
README.md           //项目的说明文件
yarn.lock           //依赖的安装包 (一般不用动)  

(1)public(静态资源不会被打包)

manifest.json 缓存使用 App名称 图标 图片大小 主色调 等配置

logo192.png || logo512.png 启动图标

robots.txt 爬虫协议 设置网站是否允许爬虫搜索到 

# https://www.robotstxt.org/robotstxt.html
User-agent:*
意思是允许所有爬虫搜索

(2)src

入口文件 index.js

.gitignore

设置不会被git上传的文件

# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.gitignore
.pnp.js
.gitignore
# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

3、非弹射状态配置

cnpm run eject webpack深度开发设置,操作不可逆转

React官方不推荐 执行cnpm run eject

弹射的作用可以看到脚手架所有的配置,进行深度开发

设置别名,最新版配置

下载

npm install react-app-rewired customize-cra --save-dev

cnpm install react-app-rewired customize-cra --save-dev

/* package.json */
"scripts": {
-   "start": "react-scripts start",
+   "start": "react-app-rewired start",
-   "build": "react-scripts build",
+   "build": "react-app-rewired build",
-   "test": "react-scripts test --env=jsdom",
+   "test": "react-app-rewired test --env=jsdom",
}

根目录下增加文件config-overrides.js 设置别名

//在根目录创建
/* config-overrides.js */
const path = require('path');
const { override,addWebpackAlias } = require('customize-cra');
//customize-cra  在不弹射情况下 复写 webpack 配置
module.exports = override(
         addWebpackAlias({        
            "@": path.resolve(__dirname, "src")
        })
)

路由Router

src>创建 components>	layout	>tab.jsx
					 main	>index>index.jsx
						    >list>index.jsx
						    >test>index.jsx
 src>创建 router >index.js

下载模块

npm i react-router-dom -S

cnpm i react-router-dom -S

入口文件 index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from '@/App.jsx';
import * as serviceWorker from './serviceWorker';
+ import { HashRouter as Router } from "react-router-dom";
ReactDOM.render(
+   <Router>
    	<App />
+   </Router>
    , document.getElementById('root'));
    
serviceWorker.unregister();

router >index.js

import React, { Fragment } from "react";
import { Route, Redirect, Switch } from "react-router-dom";
import Index from "@/components/main/index/index.jsx"
import List from "@/components/main/list/index.jsx"
import Test from "@/components/main/test/index.jsx"
export default class extends React.Component {
    render() {
        return (
            <Fragment>
                <Switch>
                    <Route path="/index" component={Index} />
                    <Route path="/list" component={List} />
                    <Route path="/test" component={Test} />
                    <Redirect path="/" to="/index" />
                </Switch>
            </Fragment>
        )
    }
} 

src > compoonents > layout > tab.jsx 

import React from "react";
import { withRouter, Link } from "react-router-dom";
import { TabBar } from 'antd-mobile';
class Tab extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            selectedTab: 'blueTab',
            hidden: false,
            fullScreen: false,
        };
    }
    render() {
        return (
            <div style={{ position: 'fixed', width: '100%', bottom: 0 }}>
                <TabBar
                    unselectedTintColor="#949494"
                    tintColor="#33A3F4"
                    barTintColor="white"
                    hidden={this.state.hidden}
                >
                    <TabBar.Item
                        title="Glp"
                        key="Glp"
                        icon={
                            <Link to="/index">
                                <div style={{
                                    width: '22px',
                                    height: '22px',
                                    background: 'url(https://zos.alipayobjects.com/rmsportal/sifuoDUQdAFKAVcFGROC.svg) center center /  21px 21px no-repeat'
                                }}
                                />
                            </Link>
                        }
                        selectedIcon={<div style={{
                            width: '22px',
                            height: '22px',
                            background: 'url(https://zos.alipayobjects.com/rmsportal/iSrlOTqrKddqbOmlvUfq.svg) center center /  21px 21px no-repeat'
                        }}
                        />
                        }
                        selected={this.state.selectedTab === 'blueTab'}
                        onPress={() => {

                            this.setState({
                                selectedTab: 'blueTab',
                            });
                        }}
                        data-seed="logId"
                    >
                    </TabBar.Item>



                    <TabBar.Item
                        icon={
                            <Link to="/list">
                                <div style={{
                                    width: '22px',
                                    height: '22px',
                                    background: 'url(https://gw.alipayobjects.com/zos/rmsportal/BTSsmHkPsQSPTktcXyTV.svg) center center /  21px 21px no-repeat'
                                }}
                                />
                            </Link>
                        }
                        selectedIcon={
                            <div style={{
                                width: '22px',
                                height: '22px',
                                background: 'url(https://gw.alipayobjects.com/zos/rmsportal/ekLecvKBnRazVLXbWOnE.svg) center center /  21px 21px no-repeat'
                            }}
                            />
                        }
                        title="Koubei"
                        key="Koubei"
                        selected={this.state.selectedTab === 'redTab'}
                        onPress={() => {
                            this.setState({
                                selectedTab: 'redTab',
                            });
                        }}
                        data-seed="logId1"
                    >
                    </TabBar.Item>



                    <TabBar.Item
                        icon={
                            <Link to="test">
                                <div style={{
                                    width: '22px',
                                    height: '22px',
                                    background: 'url(https://zos.alipayobjects.com/rmsportal/psUFoAMjkCcjqtUCNPxB.svg) center center /  21px 21px no-repeat'
                                }}
                                />
                            </Link>
                        }
                        selectedIcon={
                            <div style={{
                                width: '22px',
                                height: '22px',
                                background: 'url(https://zos.alipayobjects.com/rmsportal/IIRLrXXrFAhXVdhMWgUI.svg) center center /  21px 21px no-repeat'
                            }}
                            />
                        }
                        title="Friend"
                        key="Friend"
                        dot
                        selected={this.state.selectedTab === 'greenTab'}
                        onPress={() => {
                            this.setState({
                                selectedTab: 'greenTab',
                            });
                        }}
                    >
                    </TabBar.Item>

                    <TabBar.Item
                        icon={{ uri: 'https://zos.alipayobjects.com/rmsportal/asJMfBrNqpMMlVpeInPQ.svg' }}
                        selectedIcon={{ uri: 'https://zos.alipayobjects.com/rmsportal/gjpzzcrPMkhfEqgbYvmN.svg' }}
                        title="My"
                        key="my"
                        selected={this.state.selectedTab === 'yellowTab'}
                        onPress={() => {
                            this.setState({
                                selectedTab: 'yellowTab',
                            });
                        }}
                    >
                    </TabBar.Item>

                </TabBar>
            </div>
        );
    }
}

export default withRouter(Tab);

App.jsx

import React from 'react';
import './App.css';
+ import Routers from "@/router";
+ import Tabs from "@/components/layout/tab";
class App extends React.Component {
  render() {
    return (
      <div>
        <h1>我在</h1>
        <hr />
+        <Routers />	//路由跳转
+        <Tabs />		//底部导航
      </div>
    )
  }
}

export default App;

React-redux

下载插件

npm i redux@4.0.4 react@16.10.2 react-dom@16.10.2 react-redux@7.1.0 redux-immutable@4.0.0 redux-thunk@2.3.0 immutable@4.0.0  --save-dev

cnpm i redux react react-dom react-redux redux-immutable redux-thunk immutable -S -D

src > store > index.js

import {createStore,applyMiddleware} from "redux";
import {combineReducers} from "redux-immutable";
import thunk from "redux-thunk";

import indexReducer from "@/components/main/index/indexReducer";

const store = combineReducers({
    indexReducer
})
export default createStore(store,applyMiddleware(thunk));

入口文件index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from '@/App.jsx';
import * as serviceWorker from './serviceWorker';
import { HashRouter as Router } from "react-router-dom";
+ import store from "@/store";
+ import { Provider } from "react-redux";
//console.log(store);//正常   {dispatch: ƒ, subscribe: ƒ, getState: ƒ, replaceReducer: ƒ, Symbol(observable): ƒ}
ReactDOM.render(
+    <Provider store={store}>
        <Router>
            <App />
        </Router>
+    </Provider>, document.getElementById('root'));

serviceWorker.unregister();

src > components>main>index>indexReducer.js

import {fromJS} from "immutable";

const defaultState=fromJS({
    num:0,
});

export default (state=defaultState,action)=>{
    return state;
};

src > components>main>index>index.jsx

import React from "react";
import { connect } from "react-redux";
class Index extends React.Component {
    render() {
        return (
            <div>
                <h1>index</h1>
                <h1>数字{this.props.num}</h1>
            </div>
        )
    }
}
const mapStateToProps = state => {
    return {
        num: state.getIn(["indexReducer", "num"])
    }
};
const mapDispatchToProps = dispatch => {
    return {
        // dispatch({
        //     type: "INDEX_NUM_ADD",
        // })
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(Index);

axios 库 Fetch 原生 flyio

微应用时代 uni-app

代理

src下创建 setupProxy.js

//模块直接有,不需要下载
var proxy = require("http-proxy-middleware");
module.exports = function(app) {
    app.get("/test",(req,res)=>{
        res.send("run");
    })
  app.use(
    proxy("/apis", {
      //    我要代理的主机
      target: "https://cnodejs.org",
      changeOrigin: true,
      pathRewrite: {
        "^/apis": ""
      }
    })
  );
};

mock(模拟数据)

下载

cnpm i mockjs -D

 setupProxy.js

//模块直接有,不需要下载
const proxy = require("http-proxy-middleware");
+ var Mock = require('mockjs')
module.exports = function(app) {
    app.get("/test",(req,res)=>{
        // 使用 Mock
+    var data = Mock.mock({
+        'list|1-10': [{
+          'id|+1': 1
+       }]
+    });
+   res.json(data);
    })
  app.use(
    proxy("/apis", {
      //    我要代理的主机
      target: "https://127.0.0.1",
      changeOrigin: true,
      pathRewrite: {
        "^/apis": ""
      }
    })
  );
};

Feach

Es6Ajax方案

Promis,axios,fetch,flyio 都支持promise API

如果返回的是字符串 使用 .text()

如果返回的是json 使用 .json()

GET请求

src > components>main>index>index.jsx

//Query String Parameters 	标准的 GET 请求
//Promise {<pending>} 原生 promise
<button onClick={this.props.getTest.bind(this)}>GET</button>


const mapDispatchToProps = dispatch => {
    return {
        getTest() {
            fetch("/apis/PHP1904/Vue/php/index.php?uname=Glp&upwd=123456", {
                method: "GET"
            }).then((data) => {
                //    console.log(data);      //body: ReadableStream 可读的流
                return data.text();
            }).then(res => {
                console.log(res);           //你好!Glp本次服务即将开始,祝你旅行愉快!
            });
        }
    }
}

POST请求

//From Data

<button onClick={this.props.PostTest.bind(this)}>Post</button>

PostTest(){
    var temp= new FormData();
    temp.append("uname","郭立鹏")
    temp.append("upwd","123456")

    fetch("/apis/PHP1904/Vue/php/txt.php", {
        method: "POST",
        body:temp
    }).then((data) => {
        //    console.log(data);
        return data.text();     //.text()
    }).then(res => {
        console.log(res);           
    });
}

async await 解决异步的先后问题

拿同步解决异步问题

await 必须写在 async 的内部

async 最终返回结果是一个 promise

await 后面跟一个promise

<button onClick={this.props.AwaitTest.bind(this)}>Await</button>

AwaitTest() {
    function testNum(num) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve(num + 1);
            },2000)
        })
    }
    testNum(1).then(res => {
        console.log(res);
    })
    // async function testAdd(num){
    //     return num+1;
    // }
    // testAdd(1).then(res=>{
    //     console.log(res);
    // })

    const testFn = async () => {
        // return await testNum(1);
        let res1 = await testNum(1);
        let res2 = await testNum(res1 + 1);
        return res2;
    }
    testFn().then(res => {
        console.log(res);
    })
    //    console.log(testFn());  Promise {<resolved>: "ok"}
},

实践 async await

<button onClick={this.props.SAwaitTest.bind(this)}>SAwait</button>

SAwaitTest() {
    const testFetch = async () => {
        var temp = new FormData();
        temp.append("uname", "郭立鹏");
        temp.append("upwd", "123456");

        let respons = await fetch("/apis/PHP1904/Vue/php/txt.php", {
            method: "POST",
            body: temp
        });
        return respons.text();
    };
    testFetch().then((res) => {
        console.log(res);
    });
}