react 组件优化+路由

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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值