react脚手架基础

本文详细介绍了React脚手架的基本使用,包括创建项目、常用命令、开发服务器启动及打包流程。深入探讨了axios在React中的应用,pubsub订阅发布机制,以及React路由的全面解析,覆盖Route、Router、Link、NavLink等核心概念。
摘要由CSDN通过智能技术生成

react脚手架基础

1、一些命令

yarn add create-react-app -g
添加脚手架到全局

npm install create-react-app -g
添加脚手架到全局

yarn create-react-app my-demo
创建脚手架

npx create-react-app my-demo
创建脚手架,但是不保存create-react-app到内存

已安装create-react-app时:create-react-app my_react_project
创建脚手架

yarn start
Starts the development server.
启动开发服务器。
开发服务器

yarn build
Bundles the app into static files for production.
将应用程序捆绑到静态文件中用于生产。
打包应用

yarn test
Starts the test runner.
开始测试运行程序。
测试

yarn eject
Removes this tool and copies build dependencies, configuration files
and scripts into the app directory. If you do this, you can’t go back!
删除此工具并复制生成依赖项、配置文件并将脚本放入app目录中。如果你这样做,你就回不去了!
配置各种文件,现在一般不用。高级工程师使用较多

2、简单的结构

public:
index.html


src:
components/person.js
app.js
index.js

index.html
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>191121_react_staging</title>
</head>
<body>
	<div id="root"></div>
</body>
</html>
person.js
//定义一个展示人员信息的组件
//1.引入React核心库
import React,{Component} from 'react'
//2.定义一个Person组件,随后暴露
export default class Person extends Component{
	render(){
		return (
			<ul>
				<li>姓名:海吉</li>
				<li>sex:女</li>
			</ul>
		)
	}
}
App.js
//App组件是所有组件的“壳子”
//1.引入react核心库
import React,{Component} from 'react'
//2.引入一些我们自定义的组件
import Person from './components/person'
//3.定义一个名为App的组件,随后暴露
export default class App extends Component{
	render(){
		return (
			<div>
				<h2>hello,React脚手架</h2>
				<Person/>
			</div>
		)
	}
}
index.js
//该文件是整个应用的入口文件,该文件需要渲染App
//1.引入react核心库
import React from 'react'
//2.引入react-dom库
import ReactDOM from 'react-dom'
//3.引入App
import App from './App'
//4.渲染App到root容器
ReactDOM.render(<App/>,document.getElementById('root'))

3、axios的使用

案例

获取GitHub上以某个字母开头点赞量最高的组件

import React, { Component } from "react";
import axios from "axios";
export default class app extends Component{
  state = {
    repoName: '',//仓库名称
    repoUrl: '',//仓库地址
    isLoading: true,//是否正在请求
    err: '',//错误信息
    keyWord:'r' //以r为搜索条件
  }
  async  componentDidMount() {
    const url = `https://api.github.com/search/repositories?q=${this.state.keyWord}&sort=stars`

    try {
      const result =await axios.get(url)
      const { name, html_url } = result.data.items[0]
      this.setState({ repoName: name, repoUrl: html_url ,isLoading :false})
    } catch (error) {
      this.setState({isLoading:false,err:error.message})
    }
  }
  render() {
    const { repoName, repoUrl, isLoading, err, keyWord } = this.state
    let content = ''
    if (isLoading) 
      content=<h2>Loading</h2>
     else if(err)content=<h2>{err}</h2>
     else content=<h2>在GitHub上以{keyWord}开头,点赞量最多的是:<a href={repoUrl}>{repoName}</a></h2>
    
    return content
  }
}

4、pubsub

要使用消息订阅,必须安装pubsub-js
yarn add pubsub-js
import PubSub from 'pubsub-js'

PubSub.publish(‘方法名’,传递的参数);

例子:
PubSub.publish(‘updateListData’, {isLoading:false,userList:items});

PubSub.subscribe(‘方法名’, (方法名,传递的数据(data))=>{
});
PubSub.subscribe(‘方法名’, (msg,data)=>{
});
注意:msg形参必须存在,(data)模式里data代表的不是参数而是方法名
但是写了而不使用会有警告,所以可以以'_'代替

例子:
PubSub.subscribe(‘updateListData’, (_,stateObj)=>{
this.setState(stateObj)
});

5、路由

Route和Router

生活中:
一、路由(可以上网的一跳线路)?路由器(管理线路的)?
二、关系:路由器是管理一个一个路由的

程序中:
一、路由(Route)、路由器(Router)
路由:key-value组合

  1.前端路由:key是你输入的地址,value组件
    你如果输入a地址,我就给看A组件
    特点:请求不会发给服务器
    备注:请求没有到达服务器,被前端路由器所捕获了。

  2.后端路由:key是:method-pathname value:function
    登录:http://172.45.23.21/login
    注册:http://172.45.23.21/register
    备注:请求实实在在到达了服务器,返回的数据是服务器定的

二、关系:路由器是管理一个一个路由的(Router里包裹着Route)

Link和NavLink

NavLink和Link都是路由的标签,点击时会根据to的地址对Route标签中的地址和文件进行匹配

注意:link外面必须包裹Router,但是直接写会报错
现在Router已经分为了BrowserRouter和HashRouter
所以使用BrowserRouter或HashRouter
为了方便,通常在主index.jsx中,包裹在<App/>外

<Link to='/home/message'>Message</Link>
<NavLink to='/home/message'>Message</NavLink>

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

NavLink比Link多了点击时的默认active样式

可以通过activeClassName="demo"这句代码修改默认的样式

BrowserRouter和HashRouter

BrowserRouter

HashRouter

Route和Switch和exact

注意: react中路由的匹配规则和vue不同
react中路由匹配时是模糊匹配
例:

<Link to='/home/message'>Message</Link>
<Route path='/home' component={Home} />
<Route path='/home/message' component={Message} />

该路由点击时,只会匹配到home

<Link to='/home'>Message</Link>
<Route path='/home' component={Home} />
<Route path='/home/message' component={Message} />

该路由点击时,会匹配到home和home/message

严格匹配

<Link to='/home/message'>Message</Link>
<Route path='/home' exact component={Home} />
<Route path='/home/message' component={Message} />

添加exact: 严格匹配,路径必须完全匹配。未开启严格匹配时, to='/home/message'匹配到的是home

注意:exact有两种写法
exact exact='true'

Switch
相当于全部的严格模式

<switch>
写在这里的路由会遵循严格模式
</switch>
Redirect

Redirect 重定向,在路由没有匹配项时,会指向redirect
例:

<Link to='/home1/message1'>Message</Link>
<Route path='/home' component={Home} />
<Route path='/home/message' component={Message} />
<Route path='/about' component={About} />

<Redirect to="/about"/>
该路由中,点击时没有可以匹配的地址,所以会匹配到about
解决路由中样式丢失问题的3个方案
<link rel="stylesheet" href="./css/bootstrap.css">

1、把导入样式的路由修改为%PUBLIC_URL%/开头,代表public绝对路径下的文件

2、删除路径开头的’.’,不使用相对路径。即:/css/bootstrap.css样式

3、使用’#‘代替’.'解决哈希模式下的问题

一般组件和路由组件之间的区别

一般组件:程序员自己写组件标签渲染的,例如<Demo a="1" b="2"/>

路由组件:靠路由给我们渲染的,例如:<Route path="/demo" component={Demo}>

区别:路由组件的props上比一般组件多了3个属性,分别是:
history:路径和跳转相关的
location:history.location
match:传递参数相关

二级路由

注意:react和vue不同,react中路由的子路由必须把路径写全

路由传参
使用es6模板字符串方法填写路径

<Link to={/home/message/detail/${msgObj.id}} >{msgObj.name}</Link>

在Route标签中接收

<Route path='/home/message/detail/:id' component={Detail} />

在Detail文件中使用props调用

const { id } = this.props.match.params

push和replace

1、可以直接在link标签中写replace={true}或push{true}来使该标签的请求为对应的方式

<Link to={`/home/message/detail/${msgObj.id}`}  push={true} >{msgObj.name}</Link>
<Link to={`/home/message/detail/${msgObj.id}`}  replace={true} >{msgObj.name}</Link>

2、借用this.props.history中的方法,定义push,repalce等方法
定义的方法可以直接在各种标签中使用

export default class HomeMessage extends Component {
  没有刷新页面,但是有push的历史记录。可以回退
  push = (id)=>{
    this.props.history.push(`/home/message/detail/${id}`)
  }
  没有刷新页面,没有repalce的历史记录。回退的是repalce请求之前所请求的历史记录
  repalce = (id)=>{
    this.props.history.replace(`/home/message/detail/${id}`)
  }
  前进
  forward = ()=>{
    this.props.history.goForward()
  }
  后退
  back = ()=>{
    this.props.history.goBack()
  }

  render() {
    return (
      <div>
        <button onClick={()=>{this.push(msgObj.id)}}>push查看</button>&nbsp;
        <button onClick={()=>{this.repalce(msgObj.id)}}>replace查看</button>
        <button onClick={this.back}>后退</button>
        <button onClick={this.forward}>前进</button>
        <hr/>
        <Route path="/home/message/detail/:id" component={MessageDetail}/>
      </div>
    )
  }
}
简写Link和NavLink
import React, { Component } from 'react'
import { NavLink } from "react-router-dom";

<!-- export default class index extends Component {
  render() {
    console.log(this.props);
    
    return (
      // <NavLink className="list-group-item" />
      <NavLink activeClassName="demo" className="list-group-item" to={this.props.to}>{this.props.children} </NavLink>
      // 简写为:
      // <NavLink activeClassName="demo" className="list-group-item" {...this.props}/>
    )
  }
} -->

<!-- 可以更加简写为: -->
export default props =><NavLink activeClassName="demo" className="list-group-item" {...props}/>


在要使用的组件中引入MyNavLink组件代替NavLink即可
import MyNavLink from "./components/MyNavLink";

Link组件和NavLink相同,只是没有activeClassName="demo"这个属性

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值