1- 组件优化
1-1 Fragment
场景: 如果父组件ul中需要嵌套li组成的子组件. ul-->div-->li
import React, { Component,Fragment } from 'react' export default class Son extends Component { render() { return ( // <Fragment> <> {/* fragment 解析时是一个空标签. 或者可以直接以空标签作为根标签 */} <li>111</li> <li>222</li> <li>333</li> </> // </Fragment> ) } }
1-2 context
场景: 假设组件嵌套关系比较多,父->子->孙子. 数据在父组件中,子组件不需要接收,孙子需要接收.可以通过context使孙子直接接受父组件数据而不是借助子组件交接.
----father.js
import React, { Component } from 'react' import Son from './Son' // export let context = React.createContext() export let {Provider,Consumer} = React.createContext() // context.Provider // 发送数据 // context.Consumer // 接收数据 export default class Father extends Component { state={ money:500 } render() { return ( <div className='box'> <h1>Father组件</h1> <Provider value={{money:this.state.money}}> <Son money={this.state.money}></Son> </Provider> {/* <context.Provider value={{money:this.state.money}}> <Son money={this.state.money}></Son> </context.Provider> */} </div> ) } }
---sonson.jsx
import React, { Component } from 'react' import {Consumer} from './Father' export default class SonSon extends Component { render() { return ( <div className='box'> <h1>sonson组件</h1> {/* 通过consumer接收 函数的形参就是传递的数据 */} <Consumer> { (e)=>{ return ( <h2>{e.money}</h2> ) } } </Consumer> </div> ) } }
1-3 错误边界处理
组件只要有一个报错,整个页面都显示空白.
----error.jsx
import React, { Component } from 'react' export default class Error extends Component { // 又报错会触发此函数 componentDidCatch(){ console.log(1111); this.setState({ flg:false }) } state={ flg:true //true: 没有报错,显示son组件, false 有报错,渲染p标签 } render() { return ( <div> {this.state.flg?this.props.children:<p>部分结构无法显示,请等待.......</p>} {/* {this.props.children} */} </div> ) } }
---father.jsx
return ( <div className="box"> <h1>错误边界处理</h1> <Error> <Son></Son> </Error> {/* <Son></Son> */} </div> )
---son.jsx
1-4 高阶组件HOC
高阶组件不是react提供的api,是自己做的封装.
高阶组件就是一个函数,这个函数默认接受一个组件作为其参数.也会有一个返回值,返回一个组件.提高组件的复用性
import React, { Component } from 'react' import One from './One' import Two from './Two' import Wone from './Wone' import Wtwo from './Wtwo' // 进一步封装处理组件 // C 形参就是要处理的组件 function WithCom(C){ return class H extends Component{ render(){ return ( <div> <C></C> <h1>哈哈哈哈</h1> </div> ) } } } // 处理one组件 // Hone 就是处理之后的组件 let Hone = WithCom(One) let Htwo = WithCom(Two) export default class Father extends Component { render() { return ( <div className='box'> <h1>father组件</h1> {/* <One></One> */} {/* <Wone></Wone> */} <Hone></Hone> <Htwo></Htwo> {/* <Two></Two> */} {/* <Wtwo></Wtwo> */} </div> ) } }
2- 路由
2-1 安装
npm i react-router-dom --save
2-2 使用
1- 路由模式组件
-
HashRouter
-
BrowserRouter
ReactDOM.render( <HashRouter> <App /> </HashRouter>, document.getElementById('root') );
2- 路由规则组件
-
Route 可以定义路由规则, 还可以作为路由占位符
-
path: 定义url
-
component: 定义对应的组件
-
{/* 路由规则 */} <Route path='/login' component={Login}></Route> <Route path='/index' component={Index}></Route> <Route path='/detail' component={Detail}></Route>
3- Switch
作用: 当匹配成功之后,不再向下匹配,直接终止匹配
{/* Switch 匹配成功即终止,不再向下执行 */} <Switch> {/* 路由规则 */} <Route path='/login' component={Login}></Route> <Route path='/index' component={Index}></Route> <Route path='/detail' component={Detail}></Route> <Route path='/index' component={Home}></Route> </Switch>
4- 重定向
Redirect 路由重定向, 一定要放在后面
- to: 定义跳转的url - from: 定义需要重定向的路径
{/* Switch 匹配成功即终止,不再向下执行 */} <Switch> {/* 路由规则 */} <Route path='/login' component={Login}></Route> <Route path='/index' component={Index}></Route> <Route path='/detail' component={Detail}></Route> {/* <Route path='/index' component={Home}></Route> */} {/* 重定向 */} {/* 匹配所有路径 */} <Redirect to='/index'></Redirect> {/* 当访问/ 时重定向到/index/home */} <Redirect exact from='/' to='/index/home'></Redirect> </Switch>
5- 404页面
注意:404页面需要放在最后
{/* 404 页面 */} <Route component={Not}></Route>
6- exact
作用: 开启精确查找, 一般都是用在path='/' 的路由规则.默认是模糊查询
<Route exact path='/' component={Index}></Route>
7- strict
作用: 严格匹配模式, 需要配合exact属性一起使用,一般针对于路径后面的/, eg, /login/ ,
<Route exact strict path='/login' component={Login}></Route>
8- 嵌套路由
二级路由组件显示在哪里就在哪里定义路由规则
<div> <h1>大首页</h1> {/* 二级路由 */} <Switch> <Route path='/index/home' component={Home}></Route> <Route path='/index/mine' component={Mine}></Route> </Switch> </div>
9- 路由导航
-
Link 导航组件
-
to: 定义跳转地址
-
{/* 导航组件 */} <div className='nav'> <Link to='/index/home'>商城</Link> <Link to='/index/mine'>个人中心</Link> </div>
-
NavLink 高亮显示的导航组件
-
to: 定义跳转地址
-
activeClassName: 选中时添加的类名,如果不设置默认添加的类名为active
-
{/* 高亮显示的导航组件, 选中时默认添加active类名 */} {/* 可以通过activeClassName 来修改添加的类名 */} <div className='nav'> <NavLink to='/index/home' activeClassName='show'>商城</NavLink> <NavLink to='/index/mine' activeClassName='show'>个人中心</NavLink> </div>
10- 编程式导航
this.props.history.push('') this.props.history.replace('') this.props.history.go(n) this.props.history.goBack() this.props.history.goForward()
11- 非路由组件使用路由
import React, { Component } from 'react' import {withRouter} from 'react-router-dom' class Back extends Component { back(){ this.props.history.go(-1) } render() { console.log(this.props); return ( <div> <button onClick={()=>this.back()}>返回</button> </div> ) } } // withRouter 处理非路由组件,使其拥有路由对象的属性及方法 export default withRouter(Back)
12- 路由传参
1- 字符串拼接url?参数&
-
传参
this.props.history.push('/fdetail?name=mlt&id='+i)
-
接收参数
this.props.location.search // ?name=mlt&id=0
处理参数
-
js处理
// 需要将参数处理成对象形式 { id:2,name:mlt } // 1. 去除? let str = this.props.location.search.substring(1) // name=mlt&id=0 console.log(str); // 2. 以&切割字符串 let arr = str.split('&') // ["name=mlt", "id=0"] console.log(arr); // 3. 单独处理每一个参数 "name=mlt" ---> {name:mlt} let obj = {} //参数对象 arr.forEach(item=>{ let arr1 = item.split('=') obj[arr1[0]]=arr1[1] })
-
借助querystring 处理参数
import qs from 'querystring' // 借助qs处理 let obj = qs.parse(str) console.log(obj);
-
2- 动态路由
-
传参
-
先定义动态路由
{/* 动态路由 */} <Route path='/mdetail/:id' component={MovieDetail}></Route>
-
跳转传参
this.props.history.push('/mdetail/'+i)
-
-
参数的接收 this.props.match.params 参数对象
<h1>movie详情页面---{this.props.match.params.id}</h1>
3- state传参
-
传参
this.props.history.push({pathname:'/bdetail',state:{id:i}})
-
参数接收 this.props.location.state
{this.props.location.state.id}
13- 路由懒加载
-
1-修改组件的引入方式
// 懒加载 // 1. 通过React.lazy()引入组件 const Login = React.lazy(()=>import('./pages/Login')) const Index = React.lazy(()=>import('./pages/Index'))
-
2-必须和React.Suspense组件一起使用,必须有fallback属性
{/* 2. 懒加载需要配置Suspense组件使用 */} {/* fallback: 定义等待组件加载时显示的结构 */} <React.Suspense fallback={<p>正在加载中.....</p>}> {/* Switch 匹配成功即终止,不再向下执行 */} <Switch> {/* 路由规则 */} <Route path='/index' component={Index}></Route> ... </Switch> </React.Suspense>