Create-react-app基本使用

# Create-react-app 安装方法

Create React App 是一个官方支持的创建 React 单页应用程序的方法。它提供了一个零配置的现代构建设置。

无需 安装或配置 Webpack 或 Babel 等工具。 它们是预先配置好并且隐藏的,因此你可以专注于代码。

# 快速开始

npx create-react-app my-app
cd my-app
npm start

# 创建应用程序

你需要在本地开发计算机上使用 Node >= 6(但在服务器上不需要)。 你可以使用 nvm (macOS/Linux) 或 nvm-windows 轻松地在不同项目之间切换 Node 版本。

要创建新应用,你可以选择以下方法之一:

# npx

npx create-react-app my-app

(npx 来自 npm 5.2+ 或更高版本,查看 npm 旧版本的说明)

# npm

npm init react-app my-app

npm init <initializer> 在 npm 6+ 中可用

# Yarn

yarn create react-app my-app

yarn create 在 Yarn 0.25+ 中可用

# 图片加载

import React, { Component } from "react";
import img1 from '../src/assets/1.jpg'

class App extends Component {
  render() {
    return (
      <div>
        <img src={img1} />
        <img src={require('../src/assets/1.jpg')} alt=""/>
      </div>
    );
  }
}

export default App;

# 父子间传值

import React, { Component } from "react";
import img1 from "../src/assets/1.jpg";
import Home from "./Home";

class App extends Component {
  constructor(props) {
    super();
    this.state = {
      num: 1,
    };
  }

  onClickHandle = (props) => {
    console.log(props);
    this.setState({
      num: this.state.num+1,
    });
  };
  render() {
    return (
      <div>
        <img src={img1} />
        <img src={require("../src/assets/1.jpg")} alt="" />
        <Home msg={this.state.num} onClickHandle={this.onClickHandle} />
      </div>
    );
  }
}

export default App;
import React, { Component } from 'react';

class Home extends Component {
    render() {
        return (
            <div>
                
                <h1>{this.props.msg}</h1>
                <button onClick = {this.props.onClickHandle.bind(this,'xxx')}>点击</button>
            </div>
        );
    }
}

export default Home;

# 同级组件传值

pubsub – - 发布 / 订阅库

# 前言

  1. Pubsubjs 是一个用 JavaScript 编写的基于主题的发布 / 订阅库。
  2. Pubsubjs 具有同步解耦功能,因此主题是异步发布的。 这有助于保持程序的可预测性,因为在使用者处理主题时,主题的发起者不会被阻塞。
  3. Pubsubjs 被设计为在单个进程中使用,并不适合多进程应用程序 (比如具有许多子进程的 Node.js-Cluster)。 如果你的 Node.js 应用程序是一个单进程应用程序,你很好。 如果它是 (或将是) 一个多进程应用程序,你最好使用 redis pub /sub 或类似的应用程序

# PubSub 使用方式

  1. react 导入库: npm install pubsub-js --save
  2. react 页面引入 PubSub : import PubSub from 'pubsub-js'
  3. pubsubjs 使用 发送消息:PubSub.publish (名称,参数) 订阅消息:PubSub.subscrib (名称,函数) 取消订阅:PubSub.unsubscrib (名称)
// home.jsx  --  传递数据
import React, { Component } from "react";
import PubSub from "pubsub-js";

class Home extends Component {
  pubsub() {
    PubSub.publish("evt", 1);
  }
  render() {
    return (
      <div>
        <button onClick={this.pubsub.bind(this)}>进行同级数据传递</button>
      </div>
    );
  }
}

export default Home;
// Hello.jsx   --- 监听数据
import React, { Component } from "react";
import PubSub from "pubsub-js";

class Hello extends Component {
  constructor(props) {
    super(props);
    PubSub.subscribe("evt", (msg, data) => {
      console.log(msg);
      console.log(data);
    });
  }

  render() {
    return (
      <div>
        <h1>hello world</h1>
      </div>
    );
  }
}

export default Hello;

# 数据请求 axios 和 模拟数据 json-server

  • json-server : npm install json-server -g
  • axios : npm install --save axios

# json-server 的使用

  1. 首先准备一个 json 文件

    {
        "data1": [{
                "id": "001",
                "name": "Sherry",
                "age": 24,
                "friends": [{
                        "id": "100",
                        "name": "friend1"
                    },
                    {
                        "id": "200",
                        "name": "friend2"
                    }
                ]
            },
            {
                "id": "002",
                "name": "Addy",
                "age": 26
            }
        ],
        "data2": {
            "id": "003",
            "name": "Jack",
            "age": 25
        },
        "data3": [{
            "id": "004",
            "name": "Rebeca",
            "age": 27
        }]
    }
  2. 使用全局 json-server 命令,启动 mock 服务。这个 mock 服务,管理的数据,就是 db.json。

    json-server --watch --port 3001 db.json
  3. 使用 json-server 支持的功能,尝试进行数据访问

# 请求 mock 模拟数据 Demo

import React, { Component } from "react";
import axios from "axios";

class Test extends Component {
  componentDidMount() {
    this.ajaxFun();
  }

  ajaxFun = () => {
    axios.get("http://localhost:4000/data1").then((data) => {
      console.log(data);
    });
  };
  render() {
    return (
      <div>
        <div>
          <h1>Test</h1>
        </div>
      </div>
    );
  }
}

export default Test;

1BiO40

# 跨域

正向代理 — 开发环境

反向代理 – 上线环境

# 反向代理和正向代理

[编辑](javascript:😉

(1) 正向代理和代理服务器

正向代理即通常所说的代理,用于代表内部网络用户向 Internet 上的服务器 (或称外部服务器,通常为 Web 服务器) 发出连接请求,并接收响应结果,执行该代理功能的服务器称为代理服务器。使用代理服务器访问外部网络时,客户端必须在局域网设置中指明代理服务器的地址以及要代理的服务的端口号。 [5]

(2) 反向代理和代理服务器

反向代理的方向与正向代理相反,指代表外部网络用户向内部服务器发出请求,即接收来自 Internet 上用户的连接请求,并将这些请求转发给内部网络上的服务器,然后将从内部服务器上得到的响应返回给 Internet 上请求连接的客户:执行反向代理服务的服务器称为反向代理服务器,反向代理服务器对外部用户表现为一个服务器

# 正向代理

正向代理,意思是一个位于客户端和原始服务器 (origin server) 之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标 (原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端才能使用正向代理。

正向代理:是一个位于客户端和原始服务器 (origin server) 之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标 (原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端才能使用正向代理。

正向代理的典型用途是为在防火墙内的局域网客户端提供访问 Internet 的途径。正向代理还可以使用缓冲特性 (由 mod_cache 提供) 减少网络使用率。

使用 ProxyRequests 指令即可激活正向代理。因为正向代理允许客户端通过它访问任意网站并且隐藏客户端自身,因此你必须采取安全措施以确保仅为经过授权的客户端提供服务。

反向代理不同之处在于,典型的正向代理是一种最终用户知道并主动使用的代理方式。例如 Chrome 浏览器中安装了 switchysharp 以后,通过 switchysharp 方便地进行代理转发服务。而为此用户必须要提前在 switchysharp 中做好设置才能达到相应的效果。

# 反向代理

反向代理服务器位于用户与目标服务器之间,但是对于用户而言,反向代理服务器就相当于目标服务器,即用户直接访问反向代理服务器就可以获得目标服务器的资源。同时,用户不需要知道目标服务器的地址,也无须在用户端作任何设定。反向代理服务器通常可用来作为 Web 加速,即使用反向代理作为 Web 服务器的前置机来降低网络和服务器的负载,提高访问效率。 [1]

优点

  1. 提高了内部服务器的安全

外部网络用户通过反向代理访向内部服务器,只能看到反向代理服务器的 IP 地址和端口号,内部服务器对于外部网络来说是完全不可见。而且反向代理服务器上没有保存任何的信息资源,所有的网页程序都保存在内部服务器上,对反向代理服务器的攻击并不能使真的网页信息系统受到破坏,这样就提高了内部服务器的安全性。

  1. 加快了对内部服务器的访问速度

在内部服务器前放置两台反向代理服务器,分别连接到教育网和公网,这样公网用户就可以直接通过公网线路访问学校服务器,从而避开了公网和教育网之间拥挤的链路。同时反向代理服务器的缓存功能也加快了用户的访问速度。 [4]

  1. 节约了有限的 IP 资源

校园网内部服务器除使用教育网地址外,也会采用公网的 IP 地址对外提供服务,公网分配的 IP 地址数目是有限的,如果每个服务器有分配 - 个公网地址,那是不可能的,通过反向代理技术很好的解决了 IP 地址不足的问题。

# 模拟请求真实的数据接口 中国天气网中的数据

  1. 找到配置文件 react-demo/node_modules/react-scripts

  2. 找到中国天气网的接口。: http://www.weather.com.cn/data/cityinfo/101320101.html

  3. 更改 react 项目的配置文件: react-demo/node_modules/react-scripts/config/webpackDevServer.config.js

    // 112行proxy
    proxy: {
      "/api": {
        target: "http://www.weather.com.cn/data/cityinfo/",  //对应自己的接口
          changeOrigin: true,
            "pathRewrite": {
              "^/api": "/"
            }
      }
    },
  4. react 组件:Test.jsx

    import React, { Component } from "react";
    import axios from "axios";
    
    class Test extends Component {
      componentDidMount() {
        this.ajaxFun();
      }
    
      ajaxFun = () => {
        axios.get('/api/101320101.html').then((data) => {
          console.log(data);
        });
      };
      render() {
        return (
          <div>
            <div>
              <h1>Test</h1>
            </div>
          </div>
        );
      }
    }
    
    export default Test;

    DsGJME

# react 路由

路由 — 根据 url 的不同来切换对应的组件。 实现 SPA 切换时不会刷新页面

自从 React 16 发布后, React Router 也发布了第五个版本,更好的支持 React 16。

官方文档链接:reacttraining.com/react-route…

React Router 是一个基于 React 之上的强大路由库,它可以让你向应用中快速地添加视图和数据流,同时保持页面与 URL 间的同步。

# react-router 与 react-router-dom 区别

import { Switch, Route, Router } from 'react-router';

import { Swtich, Route, BrowserRouter, HashHistory, Link } from 'react-router-dom';
  1. # api 方面

    React-router:

    提供了路由的核心 api。如 Router、Route、Switch 等,但没有提供有关 dom 操作进行路由跳转的 api;

    React-router-dom:

    提供了 BrowserRouter、Route、Link 等 api,可以通过 dom 操作触发事件控制路由。

    Link 组件,会渲染一个 a 标签;BrowserRouter 和 HashRouter 组件,前者使用 pushState 和 popState 事件构建路由,后者使用 hash 和 hashchange 事件构建路由。

  2. # 动态路由跳转

    React-router

    router4.0 以上 this.props.history.push (’/path’) 实现跳转;

    router3.0 以上 this.props.router.push (’/path’) 实现跳转;

    React-router-dom

    直接用 this.props.history.push (’/path’) 实现跳转

  3. # 使用区别

    react-router-dom 在 react-router 的基础上扩展了可操作 dom 的 api。

    Swtich 和 Route 都是从 react-router 中导入了相应的组件并重新导出,没做什么特殊处理。

    react-router-dom 中 package.json 依赖中存在对 react-router 的依赖,故此,不需要 npm 安装 react-router。

# 路由器

每个 React Router 应用程序的核心应该是路由器组件。对于 web 项目,react-router-dom 提供 BrowserRouter 和 HashRouter 路由器。两者之间的主要区别是它们存储 URL 和与 Web 服务器通信的方式。

  • BrowserRouter 使用常规 URL 路径,创建一个像 example.com/some/path 这样真实的 URL ,但是他们要求正确的配置服务器。具体来说,您的 web 服务器需要在所有由 React Router 客户端管理的 URL 上处理相同的页面。Create React App 在开发中即开即用地支持此功能,并附带有关如何配置生产服务器的说明。
  • HashRouter 将当前位置存储在 URL 的哈希部分中,因此 URL 看起来类似于 http://example.com/#/your/page。由于哈希从不发送到服务器,因此这意味着不需要特殊的服务器配置。

# 安装

  • 你可以用 npm 或者 yarn 安装 React Router,由于我们在构建一个 web app,所以我们在这个文档中使用 react-router-dom
npm install react-router-dom --save

# 根目录 index.js 包裹

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App'
import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
import * as serviceWorker from './serviceWorker';

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

# Route 使用

<Route path='/home' component={Home}/>
<Route path='/hello' component={Hello}/>
<Route path='/test' component={Test}/>

I0RT40

<Link to='/home'>点我去home</Link> 
<Link to='/hello'>点我去hello</Link> 
<Link to='/test'>点我去test</Link> 


<Route path='/home' component={Home}/>
<Route path='/hello' component={Hello}/>
<Route path='/test' component={Test}/>

可以动态给选中的导航增加 active 的类名

<NavLink to='/home'>点我去home  </NavLink> 
<NavLink to='/hello'>点我去hello</NavLink> 
<NavLink to='/test'>点我去test</NavLink> 

# Route 精准匹配

exact

<Route path='/' exact component={Home}/>
<Route path='/home' component={Home}/>

# Switch 防止多次渲染

<Switch>
  <Route path="/" exact component={Home} />
  <Route path="/home" component={Home} />
  <Route path="/hello" component={Hello} />
  <Route path="/test" component={Test} />
  <Route path="/test" component={Test} />
</Switch>

# 重定向

Redirect

<Redirect from='/' to='/hello' exact></Redirect>

# 路由进阶

# 高阶组件

高阶组件(HOC)是 React 中用于复用组件逻辑的一种高级技巧。HOC 自身不是 React API 的一部分,它是一种基于 React 的组合特性而形成的设计模式。

具体而言,高阶组件是参数为组件,返回值为新组件的函数。

const EnhancedComponent = higherOrderComponent(WrappedComponent);

组件是将 props 转换为 UI,而高阶组件是将组件转换为另一个组件。

HOC 在 React 的第三方库中很常见,例如 Redux 的 connect 和 Relay 的 createFragmentContainer

# withRouter

高阶组件中的 withRouter, 作用是将一个组件包裹进 Route 里面,然后 react-router 的三个对象 history, location, match 就会被放进这个组件的 props 属性中.

所以 withRouter 的作用就是,如果我们某个东西不是一个 Router, 但是我们要依靠它去跳转一个页面,比如点击页面的 logo, 返回首页,这时候就可以使用 withRouter 来做.

import { Route, Link, NavLink ,Switch,Redirect,withRouter} from "react-router-dom";
// 打印 props
componentDidMount(){
    console.log(this.props);
  }
export default withRouter(App);

LFAXmD

# 监听路由变化 history

history.listen()

componentDidMount(){
  this.props.history.listen(link =>{
    console.log(link);
  })
}

gWktwn

# 编程式导航

<button onClick={()=>this.props.history.push('/test')}>点我去test</button> 

# 路由传参

# 1、params
<Route path='/path/:name' component={Path}/>
<link to="/path/2">xxx</Link>
this.props.history.push({pathname:"/path/" + name});
读取参数用:this.props.match.params.nam

优势 : 刷新地址栏,参数依然存在
缺点:只能传字符串,并且,如果传的值太多的话,url 会变得长而丑陋。

# 2、query
<Route path='/query' component={Query}/>
<Link to={{ path : ' /query' , query : { name : 'sunny' }}}>
this.props.history.push({pathname:"/query",query: { name : 'sunny' }});
读取参数用: this.props.location.query.name

优势:传参优雅,传递参数可传对象;
缺点:刷新地址栏,参数丢失

# 3、state
<Route path='/sort ' component={Sort}/>
<Link to={{ path : ' /sort ' , state : { name : 'sunny' }}}> 
this.props.history.push({pathname:"/sort ",state : { name : 'sunny' }});
读取参数用: this.props.location.query.state 

优缺点同 query

<Route path='/web/departManange ' component={DepartManange}/>
<link to="web/departManange?tenantId=12121212">xxx</Link>
this.props.history.push({pathname:"/web/departManange?tenantId" + row.tenantId});
读取参数用: this.props.location.search

优缺点同 params

# 5、react Hooks 中获取路由参数的方式:

1. 通过 hooks 钩子函数

import { useHistory,useLocation,useParams,useMatch } from 'react-router-dom';
let history = useHistory();
history.push('/')

2. 通过函数 props 参数

function Home(props) {
    const location = useLocation();
    return (
        <div className='home'>
            <Banner />
        </div>
    )
}
Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2015-2021 zhou chen
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信