网址:https://zh-hans.reactjs.org/
1.1、概述
React 起源于 Facebook(脸书) 的内部项目,它是一个用于构建用户界面的 javascript 库,Facebook用它来架设公司的Instagram网站,并于2013年5月开源。
因为是库,只做界面展示,所以可以二次开发,阿里就是Rax。
1.2、特点
- 声明式
你只需要描述UI看起来是什么样式,就跟写HTML一样,React负责渲染UI,数据的声明
- 基于组件
组件时React最重要的内容,组件表示页面中的部分内容 -- react元素 -- 虚拟dom
- 学习一次,随处使用
使用React可以开发Web应用(React-dom),使用React可以开发移动端(react-native),可以开发VR应用(react 360)
Vue是一个框架。
React可以说它不是框架,它只是一个构建页面的JavaScript库,但是外面也认为其是一个框架。
4、开发工具的安装
-
Chrome 浏览器扩展:https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=zh-CN
-
vscode安装react开发扩展
需要注意,在react中,JavaScript代码部分里面如果涉及到DOM的class属性操作,请不要直接使用class
,原因是这个class
是es6里面的关键词,react里面需要使用className
进行替换
引入到当前的网页中
1. // React 的核心库 实现跨平台开发(pc、移动)就是创建虚拟Dom的核心库
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
2. //DOM 相关的功能 就是实现把虚拟DOM转为真实dom
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
el是一个函数,就是用来创建虚拟DOM的。虚拟DOM就是个对象。
虚拟dom的key是起到标识的作用,方便比对。
参数1:组件名 或 html标签。参数2:object | null 属性(style必须是{})。参数3:子节点(可以多个)。
通过ReactDOM.render()方法把虚拟Dom转为真实Dom。
二、JSX(替代React.createElement())但需要babel编译
2.1、简介
由于通过React.createElement()方法创建的React元素有一些问题,代码比较繁琐,结构不直观,无法一眼看出描述的结构,不优雅,开发时写代码很不友好。
React使用 JSX 来替代常规的JavaScript,JSX 可以理解为的JavaScript语法扩展,它里面的标签申明要符合XML规范要求。
jsx浏览器认识吗?
答:浏览器只能识别 js,对于jsx不能识别。浏览如果来识别jsx呢?
答:react工程化中内置了一个将jsx=》js的编译工具 => babel
xml是什么?
答:严格的标记性语言。
简单的理解,xml当作是一个严格的html语言
标签有开始就必须要有结束
<div></div> <img />
属性值必须要有引号括起来,属性名不要大写
<img src="" alt="" />
React不一定非要使用JSX,但它有以下优点:
- JSX 执行更快,因为它在编译为JavaScript代码后进行了优化
jsx是浏览不能够直接运行的,它需要一个转译器进行转译(babel),转为js
- 它是类型安全的,在编译过程中就能发现错误
- 声明式语法更加直观,与HTML结构相同,降低了学习成本,提升开发效率速
jsx语法中一定要有一个顶级元素包裹,否则编译报错,程序不能运行
js != jsx jsx => js+xml集合版本,js增强版,js有的它有,js没有它也有
一定要申明类型 type="text/babel"
默认是 type="text/JavaScript"
在项目中尝试 JSX 最快的方法是在页面中添加这个 <script> 标签,引入解析jsx语法的babel类库,注意后续的script标签块中使用了jsx语法,则一定要申明类型 type="text/babel",否则babel将不进行解析jsx语法。
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
2.2、在 jsx 中语法中的 js 表达式
2.2.1、嵌入JSX表达式 用单{}
在jsx语法中,要把JS代码写到{ }中,所有标签必须要闭合。
let num = 100
let bool = false;
// JSX 语法
var myh1 = (
<div>
{/* 我是注释 */}
{num}
{true ? "条件为真" : "条件为假"}
</div>
)
2.2.2、属性绑定动态值 不要引号,写花括号
const title = '你好世界';
// 属性 不要引号,写花括号工作中天天用
<button title={title}>{title}</button>
/* class 是es6定义类的关键词,在jsx中不能使用,只能通过 className来调用定义好的样式类 */
// class --> className一定要牢记,因为在工作,写样式就要用到
// for --> htmlFor
# jsx中绑定样式 style 只绑定对象
<div style={ {color: 'red'} }></div>
#靠3目运算完成开关操作
# 动态显示html元素 dangerouslySetInnerHTML 可以进行对html标签进行反转义
<div dangerouslySetInnerHTML={ {__html:html} }></div>
# 在react17中jsx可以直接解析html,但是对于转义后的html还不会自动转义,需要使用它
# 不转义html元素输出 {两个下划线html:html}
<div dangerouslySetInnerHTML={ {__html:html} }></div>
2.2.3、jsx渲染数组列表 //map
jsx直接遍历渲染一维数组,写上就可以
<script type="text/babel">
let arr = ["张三","李四","王五","赵六"];
let app = document.getElementById('app');
ReactDOM.render(
<div>
{/* jsx中如果是一维数组,直接写上就可以遍历渲染了 */}
{ arr }
</div>,
app
);
</script>
2.2.4、jsx渲染数组列表并处理
<script type="text/babel">
let nameList = ['张三', '李四', '王五'];
ReactDOM.render(
<div>
{
// 方案1
nameList.map((item,index) => {
return (<h3>{item}</h3>)
});
// 方案2 【推荐】
nameList.map((item,index) => <h3>{item}</h3>);
</div>,
document.getElementById('app')
);
</script>
三、React脚手架
React团队主要推荐使用create-react-app来创建React新的单页应用项目的最佳方式。
第三方的,官方觉得不错,就用了。
React脚手架(create-react-app)意义
- 脚手架是官方推荐,零配置,无需手动配置繁琐的工具即可使用
- 充分利用 Webpack,Babel,ESLint(代码规范)等工具辅助项目开发
- 关注业务,而不是工具配置
create-react-app会配置你的开发环境,以便使你能够使用最新的 JavaScript特性,提供良好的开发体验,并为生产环境优化你的应用程序。
你需要在你的机器上安装 Node >= 8.10 和 npm >= 5.6。
建议可以安装 js包管理工具 yarn (facebook开发的) --- 速度会快一些
npm i -g yarn
3.1、创建React项目
npx create-react-app 项目名 // 创建项目,时间会有点的久
纯字母,不能大写,不能带空格
cd 项目名 // 进入到安装项目中
npm start // 启动项目
npx 就是5.6之后自带的,属于在线使用create-react-app
3-2、react关闭浏览器默认弹出
npm i -D cross
yarn add cross-env --dev
官网
调试 npm start 的命令
或
4.1、组件
组件允许你将 UI 拆分为独立可复用的代码片段,并对每个片段进行独立构思。从概念上类似于 JavaScript 类或函数。
它接受任意的入参(props),并返回用于描述页面展示内容的 React元素(jsx)。 定义好的组件一定要有返回值
react中定义组件的方式2种:
函数组件 (无状态组件/UI组件)
类组件 (状态组件/容器组件)
一个个jsx就是一个个组件。
4.2.1、函数创建组件 rfc
- 函数组件(无状态组件):使用JS的函数创建组件
- 函数名称必须以大写字母开头,
- 函数组件必须有返回值(jsx),表示该组件的结构,且内容必须有顶级元素
import React from 'react' 这句话17之前必须要写
import React from 'react'
// 函数名首字母必须大写
function Hello() {
return (
<div>这是第一个函数组件</div>
)
}
export default Hello;
快捷键 rfc
4.2.2、类组件 rcc
- 使用ES6语法的class创建的组件(状态组件)
- 类名称必须要大写字母开头
- 类组件要继承React.Component父类,从而可以使用父类中提供的方法或者属性
- 类组件必须提供 render 方法,用于页面结构渲染,结构必须要有顶级元素,且必须return去返回
import React from 'react'
// 创建class类,继承React.Component,在里面提供render方法,在return里面返回内容
class Hello extends React.Component{
render(){
return (
<div>这是第一个类组件</div>
)
}
}
快捷键 rcc
4.3、父传子(props[只读属性]))单向数据流
props中的数据是不能被修改的,只能读取。
组件间传值,在React中是通过只读属性 props 来完成数据传递的。
props:接受任意的入参,
并返回用于描述页面展示内容的 React元素。
props是一个单向数据流。
4.3.1、函数组件
【父】通过属性方式传参
【子】通过函数入参props接收,然后解构{}使用
4.3.2、类组件
【父】通过属性方式传参
【子】通过props接收,然后解构{}使用
父
子
五、React事件处理
5.1、事件绑定
React 元素的事件处理和 DOM 元素的很相似,但是有一点语法上的不同:
React 事件的命名采用小驼峰式,而不是纯小写。onClick onChange
- 使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串。
onClick={this.fn} // 绑定实现方法一定要用{函数或方法}
// 注函数或方法默认不用小括号,否则加 箭头
- 类组件与函数组件绑定事件是差不多的,只是在类组件中绑定事件函数的时候需要用到this,代表指向当前的类的引用,在函数中不需要调用this
函数组件
类组件
类组件的强制刷新视图
改变this跑偏的问题:也是用箭头函数柯里化。
5.2、事件对象
React中可以通过事件处理函数的参数获取到事件对象,
它的事件对象叫做:合成事件(底层是发布订阅),
即兼容所有浏览器,无需担心跨浏览器兼容问题,此事件对象还拥有和浏览器原生事件相同的接口,包括 stopPropagation()和 preventDefault(),
如果你想获取到原生事件对象,可以通过 e.nativeEvent 属性来进行获取。
作用:获取dom元素或数据传值
react中的实现没有提供像vue中的事件修饰符,像冒泡和默认行为,需要开发者自行解决。
推荐!!!
5.3、类的this指向问题(不解决是undefined)
在JSX事件函数方法中的 this,默认不会绑定 this指向。如果你忘记绑定,当你调用这方法的时候, this 的值为 undefined。所以使用时一定要绑定好this的指向。
this指向针对的是类组件,函数组件没有this问题,因为函数没有this
两种方案:bind 、 箭头
- 构造方法(只执行一次,性能最好)中绑定
constructor(props){
super(props)
// 在构造方法中指定this指向 <button onClick={this.fun()}>按钮</button>
this.fun = this.fun.bind(this)
}
- 申明是使用bind绑定(会不停的渲染,不停地绑)
<button onClick={this.fun.bind(this)}>按钮</button>
- 箭头函数绑定
<button onClick={(evt) => this.fun(evt)}>按钮</button>
-
定义事件方法使用箭头函数来绑定(用的最多!!!!!)
// 通过箭头函数定义事件方法,也能解决this指向问题
一、State状态(类组件的)
state状态只在class类组件才有,函数组件没有此功能。
函数组件在react16.8以后提供了hooks辅助函数来模拟状态。
1.1、基本使用
状态(state)即数据,是组件内部的私有数据,只能在组件内部使用 (读取和修改)
state的值是对象,表示一个组件中可以有多个数据
通过this.state来获取状态,react中没有做数据代理
state数据值可以修改,但是想要让视图更新必须用 this.setState
state可以定义在类的构造方法中也可以写在类的成员属性中
1.2、修改状态
state中的值不能直接通过修改state中的值来进行修改数据操作,react提供一个this.setState方法来完成state数据的修改操作
官方推荐用回调
1.3、props与state区别
- props 中存储的数据,都是外界传递到组件中的
- props 中的数据,都是只读的
- state 中的数据,都是可读可写的
- props 在函数声明或类申明的组件中都有
- state 只有类申明的组件中才有
二、props进阶
2.1、children属性(类和函数组件都有)
props.children属性,表示组件标签的子节点,当组件标签有子节点时,props就会有该属性,与与普通的props一样,其值可以使任意类型。单标签和双标签中没有数据都是没有此属性。
既能传数据也能传结构(类似插槽)。
在父组件的【子组件双标签】内写东西,在子可以通过【this.props.chidren】使用。
2.2、类型限制(prop-types)15.5之后移除了,需要自己npm安装
对于组件来说,props是外部传入的,无法保证组件使用者传入什么格式的数据,简单来说就是组件调用者可能不知道组件封装着需要什么样的数据,如果传入的数据不对,可能会导致程序异常,所以必须要对于props传入的数据类型进行校验。
#安装校验包
npm i -S prop-types
# 在组件中导入
import PropTypes from 'prop-types'
# 约束类型
//# 函数组件
function App(){}
// 验证规则
App.propTypes = {
prop-name:PropTypes.string
}
//# 类组件
class App extends Component{
// 类内部完成 检查
static propTypes = {
prop-name:PropTypes.string
}
}
2.3、默认值(defaultProps)
如果props没有属性没有传过数据,为了不让程序异常,可以设置其默认值。
//# 函数组件
function App(){}
App.defaultProps = {
title: '标题'
}
//# 类组件
class App extends Component {
static defaultProps = {
title: '标题'
}
}
三、表单处理
3.1、受控组件(工作用的偏多一点)
将state与表单项中的value值绑定在一起,
有state的值来控制表单元素的值,
称为受控组件。
绑定步骤:
- 在state中添加一个状态,作为表单元素的value值
- 给表单元素绑定change事件,将表单元素的值设置为state的值
子传父
删除写在父
子接收返回index
进阶
再进阶=>拆分写法
拆分!!!
单个复选框
多个复选框
全选
复选完成全选
3.2、非受控组件(工作用的偏少一点)ref
不使用状态控制,自由了
操作dom工作中没有操作数据方便
没有和state数据源进行关联的表单项,而是借助ref,使用元素DOM方式获取表单元素值
使用步骤
- 调用 React.createRef() 方法创建ref对象
- 将创建好的 ref 对象添加到文本框中
- 通过ref对象获取到文本框的值
公司里用的最多的!!
不讲武德简写法!=>少用吧
四、生命周期(类组件)
函数组件无生命周期,生命周期只有才拥有。
生命周期函数指在某一时刻组件会自动调用并执行的函数。React每个类组件都包含生命周期方法,以便于在运行过程中特定的阶段执行这些方法。例如:我们希望在第一次将其呈现到DOM时设置一个计时器Clock。这在React中称为“安装”。我们也想在删除由产生的DOM时清除该计时器Clock。这在React中称为“卸载”。
React lifecycle methods diagram
constructor(props)
挂载时执行,构造方法,第1个执行的方法,只执行一次,一般做初始化
React组件的构造函数在挂载之前被调用。在实现React.Component构造函数时,需要先在添加其它内容前,调用super(props),用来将父组件传来的props绑定到继承类中。
static getDerivedStateFromProps(nextProps, prevState)
副作用钩子方法
作用就是把props转成state
在挂载和更新都会执行,n次
此方法是react16.3之后新增,会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。它应返回一个对象来更新 state,如果返回 null 则不更新任何内容。
此方法适用于罕见的用例,即当前组件的 state 的值在任何时候都取决于 props传入。
更新了会触发他 ,一更新数据就变回刚接收的状态了,所以不要直接 return nextProps
render()
render()方法是必需的,它主要负责组件的渲染,会被重复调用n次
能写网络请求,但是不能更新,会死循环
最消耗性能:
优化,把继承的Component 换成 PrueComponent,但是\
所以优化换成update
自己写太麻烦
yarn add lodash
用lodash做递归比对
祖先节点状态发生改变,自己会更新,对自己没影响时要不更新做优化.
componentDidMount
它会在组件挂载后(插入 DOM 树中)立即调用。依赖于 DOM 节点的初始化应该放在这里。如需通过网络请求获取数据,此处是实例化请求的好地方。
挂载时
shouldComponentUpdate(nextProps, nextState)
减少组件的重复渲染
当 props 或 state 发生变化时,shouldComponentUpdate() 会在渲染执行之前被调用。返回值默认为 true则组件继续渲染,为false则当前组件不会渲染。首次渲染或使用 forceUpdate() 时不会调用该方法。此方法仅作为性能优化的方式而存在。你也可以考虑使用内置的 PureComponent 组件,而不是手动编写 shouldComponentUpdate()。PureComponent 会对 props 和 state 进行浅层比较,并减少了跳过必要更新的可能性。
当this.setState()修改了state中的数据后,当前组件将重新渲染,同时也会重新渲染子组件,但只会渲染当前组件子树(当前组件以其所有子组件)
getSnapshotBeforeUpdate(prevProps, prevState)
在最近一次渲染输出(提交到 DOM 节点)之前调用。它使得组件能在发生更改之前从 DOM 中捕获一些信息,此生命周期的任何返回值将作为参数传递给 componentDidUpdate()
componentDidUpdate(prevProps, prevState, snapshot)
会在数据更新后会被立即调用。首次渲染不会执行此方法。
componentWillUnmount()
会在组件卸载及销毁之前直接调用。在此方法中执行必要的清理操作
ref组件传值
跨组件通信 Context全局上下文
生产与消费 => 可以存取数据 先生产后消费
在react没有类似vue中的事件总线来解决这个问题。在实际的项目中,当需要组件间跨级访问信息时,如果还使用组件层层传递props,此时代码显得不那么优雅,甚至有些冗余。在react中,我们还可以使用context来实现跨级父子组件间的通信。
Context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法。Context 设计目的是为了共享那些对于一个组件树而言是“全局”的数据。
在React的Context中,数据我们可当成商品,发布数据的组件会用provider身份(卖方),接收数据的组件使用consumer身份(卖方)
子孙
或 静态属性!!!主要用这种
改数据
进阶 不允许导出解构
自己导出前做操作
网络请求
npm i -S axios
取消请求CancelToken
跨域解决方案
jsonp(模拟get)/CORS(跨域资源共享)靠死/代理/iframe/postMessage/window.name/WebSocket
react的代理实现跨域
在配置在src/setupProxy.js文件,并通过npm安装http-proxy-middleware,代理中间件模块
创建 src/setupProxy.js
安装模块
npm i -S http-proxy-middleware
const {createProxyMiddleware: proxy} = require('http-proxy-middleware')
module.exports = app => {
app.use('/api', proxy({
target: 'http://localhost',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}))
}
高阶组件(HOC)
高阶组件(Higher-Order Components)就是一个函数,传给它一个组件,它返回一个新的组件。
高阶组件:就相当于手机壳,通过包装组件,增强组件功能。
实现步骤:
- 首先创建一个函数
- 指定函数参数,参数应该以大写字母开头
- 在函数内部创建一个类组件或函数组件,提供复用的状态逻辑代码,并返回
- 在该组件中,渲染参数组件,同时将状态通过prop传递给参数组件(可选,如有)
- 调用该高阶组件,传入要增强的组件,通过返回值拿到增强后的组件,并将其渲染到页面
作用:
进行权限控制
路由限制
访问统计
统一布局(公共样式,头尾)
高阶组件的弊端:会增加层级,会影响组件的渲染速度,而且父子会变成爷孙。
返回类的话要这样
占位符=>顶层api=>Fragment 简写 <></>
装饰器@ es8的预案,现在还没通过。 【类】组件的。
装饰器是一种函数,写成 @函数名。它可以放在类和类方法的定义前面。react脚手架创建的项目【默认是不支持装饰器】,需要手动安装相关模块和添加配置文件。
安装
npm i -D customize-cra react-app-rewired
修改package.json文件中scripts命令
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-scripts test",
"eject": "react-scripts eject"
}
在项目根目录中添加config-overrides.js配置文件
此文件就是react工程用于增量配置react中的webpack配置,
可以理解为就是webpack.config.js的扩展文件,是给node所用,commonjs规范。
const {resolve}= require('path')
const {addDecoratorsLegacy, override} = require('customize-cra')
const customize = () => (config) => {
config.resolve.alias['@'] = resolve('./src')
return config
}
module.exports = override(
addDecoratorsLegacy(),
customize()
)
如果想要用@有代码提示
jsconfig.json要配置,和vue一样
封装--高阶组件
根据用户名,显示不同的电话号码权限
不是admin的显示123****4564
memoization ( [类组件] 的计算属性-记忆组件)
连续两次相同传参,第二次会直接返回上次的结果,每次传参不一样,就直接调用函数返回新的结果,会丢失之前的记录,并不是完全记忆,可以在它的参数中传入state数据从而实现了类似Vue中的计算属性功能
npm i -S memoize-one
yarn add memoize-one
# 引入
import memoizeOne from 'memoize-one'
# 使用
getValue = memoizeOne((x,y) => x+y)
css-in-js (sass写法,js文件格式) 样式组件
用它是因为本身直接引css没有作用域
代码提示
CSS-in-JS是一种技术,而不是一个具体的库实现。简单来说CSS-in-JS就是将应用的CSS样式写在JavaScript文件里面,而不是独立为一些css,scss或less之类的文件,这样你就可以在CSS中使用一些属于JS的诸如模块声明,变量定义,函数调用和条件判断等语言特性来提供灵活的可扩展的样式定义。CSS-in-JS在React社区的热度是最高的,这是因为React本身不会管用户怎么去为组件定义样式的问题,而Vue有属于框架自己的一套定义样式的方案。
styled-components 应该是CSS-in-JS最热门的一个库,通过styled-components,你可以使用ES6的标签模板字符串语法,为需要styled的Component定义一系列CSS属性,当该组件的JS代码被解析执行的时候,styled-components会动态生成一个CSS选择器,并把对应的CSS样式通过style标签的形式插入到head标签里面。动态生成的CSS选择器会有一小段哈希值来保证全局唯一性来避免样式发生冲突。
npm i -S styled-components
样式文件就是.js文件
样式的继承,标签公共样式
封装 样式传递 对象也可以{{}}
路由
4.1、介绍
现代的前端应用大多数是SPA(单页应用程序),也就是只有一个HTML页面的应用程序。因为它的用户体验更好、对服务器压力更小,所以更受欢迎。为了有效的使用单个页面来管理多页面的功能,前端路由应运而生。
- 前端路由功能:让用户从一个视图(组件)导航到另一个视图(组件)
- 前端路由是一套映射规则,在React中,是URL路径与组件的对应关系
- 使用React路由简单来说,就是配置路径和组件
通过组件完成路由规则的定义
可以通过代码做 [ 配置式路由 ]
路由使用
Declarative routing for React apps at any scale | React Router
安装路由模块(第三方)
npm i -S react-router-dom@5
最新是6,所以要写@5
403是操作无权限的时候
204是删除的时候,因为没有响应体
相关组件
- Router组件:包裹整个应用,一个React应用只需要使用一次
Router: HashRouter和BrowserRouter
HashRouter: 使用URL的哈希值实现 (localhost:3000/#/first)
BrowserRouter:使用H5的history API实现(localhost3000/first)
- Link/NavLink组件:用于指定导航链接(a标签)
最终Link会编译成a标签,而to属性会被编译成 a标签的href属性
- Route组件:指定路由展示组件相关信息(组件渲染)
path属性:路由规则,这里需要跟Link组件里面to属性的值一致
component属性:展示的组件
1.定义路由模式
定义项目使用路由,在入口文件/src/index.js文件中
2.定义路由规则和匹配成功的渲染组件
3.在浏览器中输入后尝试匹配
声明式导航
使用Link或NavLink组件完成声明式导航的定义
Link/NavLink区别
- Link组件不会根据路由的变化而添加或修改编译后html标签中的属性
- NavLink会根据路由的变化而自动修改编译后html标签中的属性
如果当前的路由规则和Navlink中的To所写的规则一致则添加class样式,
默认名称为 active,可以通过activeClassName来修改匹配成功后样式名称。
严格模式
NavLink也是模糊匹配
当不想每个都写严格,就使用 Switch 只匹配一个
重定向,写在最下面!!!
在最上面要加exact,少用exact
编程式导航(最常用)!!!
react-router-dom中通过history对象中的push/replace/go等方法实现编程式导航功能。
默认只有 [ 直接 ] 渲染的组件才有this.props,才有 history、location、match 三个对象.
父要把自己的得到路由对象 通过 父传子 加上
编程式导航
withRouter 高阶组件
把不是通过路由直接渲染出来的组件,将react-router 的 history、location、match 三个 路由对象 传入props对象上
路由参数
路由参数:在Route定义渲染组件时给定动态绑定的参数。
React路由传参方式有三种:
动态路由参数(param)
根据id获取详情
以“/detail/:id”形式传递的数据
在落地组件中通过this.props.match.params得到
查询字符串(search)
通过地址栏中的 ?key=value&key=value传递
在落地组件中通过this.props.location.search得到
隐式传参(state),通过地址栏是观察不到的 !!! (埋点!!!)
通过路由对象中的state属性进行数据传递
在落地组件中通过this.props.location.state得到
嵌套路由/子路由
当你想改父路由名字时要手动把所有的都改了
在子里定义父路由的变量
render() {
// 获取前缀,供后续地址做路由拼接
let prefix = this.props.match.path;
return (
<div>
<h1>欢迎使用后台管理程序</h1>
<Route path={`${prefix}/user`} component={User}></Route>
<Route path={`${prefix}/goods`} component={Goods}></Route>
</div>
);
}
三种路由渲染方式
1、component (组件对象或函数)
<Route path="/home" component={Home} />!!!!!!!!!!!
或
<Route path="/home" component={(router)=><Home {…router} />} />
2、render (函数)!!!!!权限判断
<Route path="/home" render={router=><Home {…router} />} />
3、children (函数或组件)
// 全匹配
<Route path="/about" children={router =>{
return <div>children渲染</div>
}} />
或
// 精确匹配 , 一般不用
<Route path="/about" children={<About />} />
模拟全局守卫!!!权限
生命周期先是孩子后是老子
过渡动画组件
1.1、给组件使用过渡动画
npm i -S react-transition-group
www就是classname
1.2、集合animate.css
可控度不高
网址:Animate.css | A cross-browser library of CSS animations.
npm install animate.css --save
1.3、列表过渡
1.3、利用高阶组件给组件添加动画
只是想对指定的页面有路由切换效果
并不想让所有的路由都有动画效果,只是想对指定的页面有路由切换效果,可以利用高阶组件来完成。让组件有动画