react-router之Route渲染内容的三种方式

2020-10-20  本文已影响0人  低头看云

react-router之Route渲染内容的三种方式

结论: Route渲染优先级: children > component > render

component

 <Route path="/user" component={UserPage} />

官方: When you use component (instead of render or children, below) the router uses React.createElement to create a new React element from the given component. That means if you provide an inline function to the component prop, you would create a new component every render. This results in the existing component unmounting and the new component mounting instead of just updating the existing component. When using an inline function for inline rendering, use the render or the children prop (below).

翻译: 当你使用component(而不是render, children), router使用React.createElement从给定组件创建一个新的React元素。

这意味着如果您为组件道具提供内联函数,那么您将在每次呈现时创建一个新组件。这将导致现有组件卸载和新组件挂载,而不只是更新现有组件。

当使用内联函数进行内联呈现时,请使用render或children道具(下面)。

Render: func()

官方: Instead of having a new React element created for you using the component prop, you can pass in a function to be called when the location matches. The render prop function has access to all the same route props (match, location and history) as the component render prop

翻译: 不使用components属性为您创建一个新的React元素,使用render您可以传入一个函数,以便在位置匹配时调用。渲染道具功能可以访问所有相同的路径道具(match,location和history)作为组件渲染道具

案例

// app.js
import React, { useState } from 'react'

import { BrowserRouter as Router, Link, Route } from 'react-router-dom'
import UserPage from './views/UserPage'
import HomePage from './views/HomePage'
import LoginPage from './views/LoginPage'

function App() {
  const [count, setCount] = useState(0)
  return (
    <div className="App">
      <div>
        Count : {count}
        <button onClick={() => setCount(count + 1)}>我是按钮</button>
      </div>
      <Router>
        <Link to="/">首页</Link>
        <Link to="/user">用户</Link>
        <Link to="/home">主页</Link>
        <Link to="/login">登录</Link>
     
          {/* component 属性 */}   
      <Route path="/user" component={() => <UserPage count={count} />} />
      {/*  <Route path="/user" render={() => <UserPage count={count} />} /> */} 
        <Route
          path="/home"
          render={() => {
            console.log('homepage')
            return <HomePage />
          }}
        />
        <Route path="/login" children={LoginPage} />
      </Router>
    </div>
  )
}

export default App

 <Route path="/user" component={() => <UserPage count={count} />} />
// userPage.js
import React, { PureComponent } from 'react'

class UserPage extends PureComponent {
  componentDidMount() {
    console.log('UserPage渲染了。。')
  }
  componentWillUnmount() {
    console.log('userPage卸载了。。。')
  }
  render() {
    // 挂载了 history: location match:三个对象
    console.log('UserPage prosp', this.props)
    return <div>UserPage == Count:{this.props.count}</div>
  }
}

export default UserPage
image-20201019155418455
<Route path="/user" render={() => <UserPage count={count} />} />
image-20201019155826649

children: func

 <Route path="/user" children={() => <UserPage count={count} />} />
image-20201019162516501

Route核心渲染源码

 return (
          <RouterContext.Provider value={props}>
              {match // 是否与地址匹配
                ? children // 1.优先判断children是否存在
                  ? typeof children === 'function' // 存在情况下判断children是否是个函数
                    ? children(props)
                    : children
                  : component // 2.判断是否是一个component,
                  ? React.createElement(component.props) // 是, 创建一个元素
                  : render // 3. 判断是否是render属性; render传入是一个函数
                  ? render(props) // 执行render
                  : null // 否, 输出是空的
               
                : children // 不匹配,判断是否是有children
                ? typeof children === 'function' // 判断children是否是个函数
                  ? children(props) // 执行函数
                  : children // 组件直接渲染
                : null}
            </RouterContext.Provider>
          )
     
上一篇 下一篇

猜你喜欢

热点阅读