极品-React中的DOM虚拟DOM,与deff算法,router

Posted 哈比老乌龟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了极品-React中的DOM虚拟DOM,与deff算法,router相关的知识,希望对你有一定的参考价值。

在react中state中存放的是数据
初次渲染时react会根据state(model),创建出一个虚拟DOM树
然后经过render将虚拟DOM形成出真实的DOM
当数据发生变化的时候(setState())他会生成一个新的虚拟DOM树
通过deff算法计算上一次的值和新更新的值有什么新的变化
最后render只会将更新的内容渲染到真实DOM上

安装
安装react-router-dom
yarn add react-router-dom --save
代码中基本使用

import React, Component  from "react";
import  BrowserRouter,Route,Switch  from "react-router-dom";
import routers from "./router/index";
class App extends Component<any,any>
  render(): React.ReactNode 
    return (
        <BrowserRouter>
            
                routers.map(router=>
                    return (
                        <Route
                            path=router.path
                            component =  router.component 
                        ></Route>
                    )
                )
            
        </BrowserRouter>
    )
  

export default App

        1.写法不同:
​           一般组件:<Demo/>

​           路由组件:<Route path="/demo" component=Demo/>

​ 2.存放位置不同:

    一般组件:components

​     路由组件:pages

​ 3.接收到的props不同:

​ 一般组件:写组件标签时传递了什么,就能收到什么

​ 路由组件:接收到三个固定的属性


​      history:

​           go: ƒ go(n)

​             goBack: ƒ goBack()

​               goForward: ƒ goForward()

​                  push: ƒ push(path, state)

​                             replace: ƒ replace(path, state)
location:
     pathname: "/about"

​             search: ""

​                  state: undefined

​ match:

​ params: 
 path: "/about"
 url: "/about"

路由传参接受
方式1
通过params

<Route path='/:userId' component=User></Route>

跳转路由

this.props.history.push('/1234')

接收

this.props.match.params.userId

特点 :刷新页面数据不会丢失,但是只能传字符串

方式2 通过query

跳转路由

 this.props.history.push( pathname: '/home' , query :  id: '6666' )

接收参数

this.props.location.query.id

方式3 通过state
跳转路由

 this.props.history.push( pathname: '/home' , state:  id: '6666' )

接收参数

this.props.location.state.id

通过params传参 页面刷新 数据不会丢失 query与state传参 刷新页面数据会丢失

嵌套路由

先定义页面
Topic.js, About.js, Topic.js, A.js, B.js (将里面的文字做相应的替换)

import React from 'react'

export default class Topic extends React.Component 
    render() 
        return (
            <>
                <div>
                    Topic页面
                </div>
            </>
        )
    

Home2.js

import React from 'react'
import  Link  from 'react-router-dom'

export default class Home extends React.Component 
    render() 
        return (
                <div>
                    <ul>
                        <li>
                            <Link to="/">Home2</Link>
                        </li>
                        <li>
                            <Link to="/about">About2</Link>
                        </li>
                        <li>
                            <Link to="/topic">Topics2</Link>
                        </li>
                    </ul>

                    <hr/>
                    /* 子页面 */
                    /* 所有子组件 */
                    this.props.children
                </div>
        )
    

router.js

import React from 'react'
import  HashRouter as Router, Route, Link, Switch, useRouteMatch, useParams  from 'react-router-dom'

import Main from './Main'
import About from './About'
import Topic from './Topic'

import Home from './Home'
import A from './A'
import B from './B'

/**
 * 这个页面就是 最终输出页面
 * 在项目根目录的 index.js 文件里面
 * 
 * import Router from './pages/router_demo/router02/router';
 * ReactDOM.render(<Router />, document.getElementById('root'));
 */
export default class IRouter extends React.Component 

    render() 
        return (
            <>
                <Router>
                    /* 只能有一个根节点 */
                    <Home>
                        /* 页面路由,一个 Route 代表一个页面 */
                        /* 4.0  版本开始允许加载多个路由,所以建议加上 exact 进行精准匹配*/
                        <Route exact=true path="/" component=Main/>
                        <Route exact=true path="/about" component=About/>
                        <Route exact=true path="/topic" component=Topic/>
                        /* 嵌套路由,不能在父级家 exact,因为先要匹配父级然后才能匹配子集 */
                        /* 比如:/nested/a , 会先匹配父级 /nested 饭后才能匹配 /nested/a */
                        <Route path="/nested" component=() => <Nested /> />
                    </Home>
                </Router>
            </>
        )
    


/**
 * 函数组件
 * @param * props 
 */
export function Nested(props) 
    // 获取route的匹配数据
    // path 路径, url 路径, params 参数
    const  path, url, params  = useRouteMatch()
    // 获取 path 参数, http://localhost:3000/a/:number
    // const  number  = useParams()

    console.log(path, url, params)
    return (
        <>
            <ul>
                <li>
                    <Link to=`$path/a`>A页面</Link>
                </li>
                <li>
                    <Link to=`$path/b`>B页面</Link>
                </li>
            </ul>
            <hr/>
            /* props.children */
            <Switch>
                <Route exact path=path component=() => <h3>嵌套路由</h3>/>
                <Route  path=`$path/a` component=A/>
                <Route  path=`$path/b` component=B/>
            </Switch>
        </>
    )


嵌套路由的重点在于,嵌套路由,不能在父级加 exact(精准匹配),因为先要匹配 父级 然后才能匹配 子集
比如:/nested/a , 会先匹配父级 /nested 后才能匹配 /nested/a

<Route path="/nested" component=() => <Nested /> />
.......  分隔符 ...........

// <Nested /> 组件的内部
// 这里的 path 就是 /nested
// `$path/a` 就是 /nested/a
<Switch>
     <Route exact path=path component=() => <h3>嵌套路由</h3>/>
     <Route  path=`$path/a` component=A/>
     <Route  path=`$path/b` component=B/>
</Switch>

以上是关于极品-React中的DOM虚拟DOM,与deff算法,router的主要内容,如果未能解决你的问题,请参考以下文章

极品-React中的DOM虚拟DOM,与deff算法,router

极品-React中的DOM虚拟DOM,与deff算法,router

关于React中的虚拟DOM与Diff算法

React 触发虚拟 DOM 输入的 onChange 事件与常规 DOM 中的输入不同。为啥是这样?

React虚拟dom中的key值

深入理解react中的虚拟DOMdiff算法