React 路由以及状态管理的用法

React 路由以及状态管理的用法_第1张图片

React 路由

安装react-router-dom

 npm install [email protected] -S
  • v5文档:React Router: Declarative Routing for React.js

  • React路由的编程特点:组件化、hooks api、withRouter

  • 安装react-router-dom(v5.3.0),会使用HashRouter、Route、Switch、Redirect、Link。

  • 使用@loadable/component(React.lazy、Suspense)实现“代码分割”。

  • 安装antd-mobile,把tabbar组件搞进来。

  • 在react-router-dom路由系统中,不是每个React组件都能访问到路由api。只有那些被Route直接包裹过的React页面组件可以通过props访问到路由api。

  • 那些未被Route直接包裹的React组件默认无法访问路由api,怎么办呢?

    • 可以通过属性继承{...props}语法,把页面组件的props(路由API)手动向后代组件传递。

    • 使用withRouter这个高阶组件,向组件中注入路由API。(非Hooks编程中用得比较多)

    • 使用react-router-dom(v5)提供的hooks api直接使用路由API。

    • 修改react-router-dom出口,把路由上下文对象抛出来,useContext()直接使用这些路由API。

  • 路由传参:params动态路由传参,query传参。

  • 嵌套视图:Route所包裹的组件中又使用了Route。

    • 在嵌套视图时,一定要用Switch把二级Route路由包裹起来。

    • 在编写Route规则,不要“一刀切地加exact”,注意exact对 / 的影响。

function App() {
  return (
    
      
    
  )
}
function List() {
  return (
    
      
    
  )
}

 在v6中如何解决“嵌套视图”的问题(v6中用element渲染组件)


  }>
  }>
    }>
    }>      
  

​
function Find() {
  return (
    
something
  ) }

路由懒加载

可以使用React.lazy 和 React Router 这类的第三方库,来配置基于路由的代码分割,实现按需加载。

import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
​
const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));
​
const App = () => (
  
    Loading...
}>                //exact 为精准匹配路由,适用于网站的首页。                             );

但由于React.lazy 和 Suspense 技术还不支持服务端渲染,所以React给我们推荐了 @loadable/component 代码示例:

import loadable from '@loadable/component'
const OtherComponent = loadable(() => import('./OtherComponent'))
function MyComponent() {
  return (
    
         
) }

注意:使用上面的库我们需要在babel文件中引入这两个插件(plugins)

{
  "presets": ["@babel/preset-react"],
  "plugins": ["@babel/plugin-syntax-dynamic-import"]
}

携带参数跳转页面

import React from 'react';
import {Route,Redirect,Switch,BrowserRouter,useHistory} from 'react-router-dom';

import T from './views/T' //导入要跳转的React页面

const B=()=>{
  const hist = useHistory()
  return (
    
{ hist.push(`/res/1fejwdhla`) }}> 页面跳转
) } function App() { return ( <> {/* 当路径为/时显示 */} {/* 使用 :id 可以将路由后面的参数以id的参数值传递到res路由的页面 */} {/* 当之前的路由都不满足时,重定向为根页面 */} ); } export default App;
import React from 'react';

export default (props => {
    console.log(props)
    return (
        
            

这是T页面

) })

 我们可以通过props可以查看到上一个页面传过来的携带过来路由信息。

React 路由以及状态管理的用法_第2张图片

状态管理

mobx

安装mobx

monbx(V6) + mobx-react(v7) 

  • 安装mobx(v6),用面向对象语法编写store和子store的代码逻辑。
  • 安装mobx-react(v7),在APP根组件中,使用
  • 在React组件中,使用inject('user')(observer(props=>(
    )))

  安装:

npm i mobx mobx-react -S

modx的使用

根store的入口文件  

//创建一个store文件
import UserStore from "./user";

class Store {
    constructor(){
        this.user= new UserStore()
        this.dd=789456
    }
    dd=456
}

export default new Store()

子store 文件

import {
  makeAutoObservable,
  observable,
  action,
  flow
} from 'mobx'

import { fetchArticleList } from '../api'

export default class UserStore {
  constructor() {
    //makeAutoObservable自动转换该类中的属性和方法
    // makeAutoObservable(target, annotations?, options?)
    // target:指定要转化的目标实例对象 一般都指向当前Clas
    // annotations: 注解对象
    // key:指定要转化的属性或方法
    // value:annotation(注解,从 mobx 引入的方法),指定要转换成什么
    // 所有 自有 属性都成为 observable。
    // 所有 getters 都成为 computed。
    // 所有 setters 都成为 action。
    // 所有 prototype 中的 functions 都成为 autoAction。
    // 所有 prototype 中的 generator functions 都成为 flow。(需要注意,generators 函数在某些编译器配置中无法被检测到,如果 flow 没有正常运行,请务必明确地指定 flow 注解。)

    // 即:把当前对象上的成员属性变成observable变量,把成员方法变成action方法。
    makeAutoObservable(this, {
      token: observable,
      list: observable,
      num: observable,
      num2: computed,
      changeNum: action,
      //当在action中需要用到同步的async/await时,建议使用 flow,编写generator的语法。
      getList: flow
    })
  }
  token = 'token'
  list = []
  num = 1
  get num2() {
    return this.num * 100
  }
  changeNum(payload) {
      this.num += payload
    }
  * getList(params) {
    const list = yield fetchArticleList(params) //此处是发送请求获取返回列表的示例
    this.list = list
  }
}

 注意:我们要在jsx页面文件中获取到store数据,我们需要使用Provider提供store数据

// 引入mobx状态管理
import { Provider } from 'mobx-react';
import store from './store';
...
 
        {/* 这里为需要store数据的jsx组件页面 */}
 
...

react  T.jsx页面

import React from 'react';

import { inject , observer} from 'mobx-react'

// 注意: 要先观察再注入即 inject(observer(...))
// 'user','dd' 为要从store注入的数据  
export default inject('user','dd')( 
    // observer(UI) 把当前组件变成观察者,当store数据发生变化时,组件将会自动更新
    observer(
        ({user,dd}) => {
            console.log(user,dd)
            return (
                
                    

这是T页面

{user.num}
{/* 调用userstore中的action方法 */}
) } ) )

React 路由以及状态管理的用法_第3张图片

你可能感兴趣的:(JavaScript,react,webpack,前端,javascript,react.js)