Leveling Up With React: React Router

Leveling Up With React: React Router

BRAD WESTFALL // MARCH 14, 2016
Link: https://css-tricks.com/learni...javascript

When I was first learning, I found lots of beginner guides (i.e. 1, 2, 3, 4) that showed how to make single components and render them to the DOM. They did a fine job of teaching the basics like JSX and props, but I struggled with figuring out how React works in the bigger picture -- like a real-world Single Page Application (SPA). Since this series covers a lot of material, it will not cover the absolute beginner concepts. Instead, it will start with the assumption that you already understand how to create and render at least one component.css

當初我學習的時候,我找到不少入門指南(第1步、第2步、第3步……)手把手地教你若是寫一個個組件,又如何把它們渲染到DOM中。雖然這些教程不少第介紹了基本概念,好比什麼是JSX,什麼是props等等,但我仍是很困惑,困惑如何在一個真實一點的項目中使用React——好比作一個真正的單頁面應用(SPA)。因爲這系列文章要涵蓋不少內容,因此咱們再也不累述初學者概念,而是假設你已經具有如何構建和渲染組件的基本知識。前端

For what it's worth, here are some other great guides that aim at beginner:java

Series Code

This series also comes with some code to play with at GitHub. Throughout the series, we'll be building a basic SPA focused around users and widgets.github

這系列文章還附帶了一些代碼放在GitHub上。經過這個系列教程,咱們將會一塊兒構建一個基於用戶和小部件的基本SPA。web

To keep things simple and brief, the examples in this series will start by assuming that React and React Router are retrieved from a CDN. So you won't see require() or import in the immediate example below. Towards the end of this tutorial though, we'll introduce Webpack and Babel for the GitHub guides. at that point, it's all ES6!後端

簡潔起見,我們這系列的範例代碼是假設你的React和React Router是經過CDN獲取的,因此,在接下來的範例代碼中,你看不到require()或import這樣的語句。在本教程結束的時候,咱們將會結束Webpack和Babel的GitHub指南。到那時,都用ES6語法來寫。

React-Router

React isn't a framework, it's a library. Therefore, it doesn't solve all an application's needs. It does a great job at creating components and providing a system for managing state, but creating a more complex SPA will require a supporting cast. The first that we'll look at is React Router.

大夥們都知道,React不是一個框架,只是一個工具庫。所以,它沒辦法解決一個應用的全部需求。React能夠很好地構建組件和管理狀態,但若是要構建一個較複雜SPA,咱們須要一些「外援」。第一個咱們將要介紹的是React Router

If you've used any front-end router before, many of these concepts will be familiar. But unlike any other router I've used before, React Router uses JSX, which might look a little strange at first.

若是你之前用過其它的前端路由工具,那這裏的不少概念你都不會陌生。但跟我之前用過的其它路由工具不一樣的是,React Router使用JSX,一開始看上去可能有一點點怪。

As a primer, this is what it's like to render a single component:

首先,渲染一個簡單的組件應該是這樣的:

var Home = React.createClass({
    render: function() {
        return (<h1>Welcome to the Home Page</h1>);
    }
});

ReactDOM.render((
    <Home />
), document.getElementById('root'));

Here's how the Home component would be rendered with React Router:

但若是用React Router來渲染這個Home組件,應該是下面這樣的:

...

ReactDOM.render((
    <Router>
        <Route path="/" component={Home} />
    </Router>
), document.getElementById('root'));

Note that <Router> and <Route> are tow different things. They are technically React components, but they don't actually create DOM themselves. While it may look the <Router> itself is being rendered to the 'root', we're actually just defining rules about how our application works. Moving forward, you'll see ths concept often: components sometimes exist not to create DOM themselves, but to coordinate other components that do.

要注意,這裏的<Router>和<Route>是兩個不一樣的東西。從技術上說,它們都是React組件,但它們不會真地建立DOM節點。雖然看起來像是<Router>自身被渲染到'root'根節點上,但實際上,咱們只是定義了咱們的應用如何工做的規則而已。在接下來的教程裏,你會常常遇到這個概念:有的組件它存在的意思不在爲了渲染DOM,而是協助其它組件渲染DOM。

In the example, the <Route> defines a rule where visiting the home page / will render the Home component into the 'root'.

在這個例子中,<Route>定義這樣一個規則:當訪問首頁/時,將渲染Home組件到'root'根節點上。

Multiple Routes

In the previous example, the single route is very simple. It doesn't give us much value since we already had the ability to render the Home component without the router being involved.

在上面這個例子中,單一路由很是簡單。但對於我們沒有價值,由於即便咱們不用router,也可以將Home組件渲染到頁面中。

React Router's power comes in when we use multiple routes to define which component should render based on which path is currently active:

React Router的做用在於咱們能夠經過多個route實現瀏覽器根據當前的url路徑,渲染對應的組件:

ReactDOM.render((
    <Router>
        <Route path="/" component={Home} />
        <Route path="/users" component={Users} />
        <Route path="/widgets" component={Widgets} />
    </Router>
), document.getElementById('root'));

Each <Route> will render its respective component when its path matches the URL. Only one of these three components will be rendered into the 'root' at any given time. With this strategy, we mount the router to the DOM 'root' once, then the router swap components in and out with route changes.

當URL與某個Route的path匹配時,這個Route對應的組件就會被渲染。在任何的時候,就有上面這幾個組件會被渲染到根節點root上。有了這個策略,一旦咱們往'root'根節點掛載這個Rooter,它就會根據路由的變化而切換組件。

It's also worth noting that the router will switch routes without making requests to the server, so imagine that each component could be a whole new page.

另外要注意的是,route之間的切換,是不須要向後端服務發出請求的,因此,想象下每一個組件多是一個全新頁面。

Re-usable Layout

We're starting to see the humble beginnings of a Single Page Application. However, it still doesn't solve real-world problems. Sure, we could build the three components to be full HTML pages, but what about code re-use? Chances are, these three components share common assets like a header and sidebar, so how do we prevent HTML repetition in each component?

咱們開始看見一個單頁面應用的雛形,但它依然無法解決一些實際問題。固然,咱們能夠將這個三個組件構建成三個完整的頁面,但代碼複用何在了?而實際中這個三個組件極可能有着共同的資源,好比頭部和側邊欄等,因此如何防止每一個組件中的HTML重複了?

Let's imagine we were building a web app that resembled this mockup:

假設咱們要構建一個相似下面這樣子的網絡應用:

clipboard.png

When you start to think about how this mockup can be broken down into reusable section, you might end up with this idea:

當你開始思考這個模型如何拆解成可重用的部件,你也許會得出下面的結果:

clipboard.png

Thinking in terms of nestable components and layouts will allow us to create resuable parts.

試想一下,嵌套的組件和佈局都應該被構建成可重用的部分。

Suddenly, the art department lets you know that the app needs a pager for searching widgets which resembles the page for searching users. With User List and Widget List both requiring the same "look" for their search page, the idea to have Search Layout as a separate component makes even more sense now:

忽然,設計部門告訴你這個應用須要一個搜索小工具的頁面,相似於用戶搜索頁面。因爲用戶列表和小工具列表長得很像,因此將搜索佈局做爲一個獨立的組件開發是有意義的。

clipboard.png

Search Layout can be a parent template for all kinds of search pages now. And while some pages might need Search Layout, others can directly use Main Layout without it:

如今,搜索佈局能夠做爲各類搜索頁頁面的父模板,即便有的頁面須要搜索佈局,有的不須要搜索佈局,而是直接嵌入主佈局。

clipboard.png

(待續。。。)

相關文章
相關標籤/搜索