[email protected]使用とソースの解析
12528 ワード
すでに開発中のreactアプリケーションであれば、より良い管理ルーティング機能を導入したいと考えています.では、react-routerはあなたの最善の選択です~react-routerバージョンは現在4.0.0に達していますが、前の安定したバージョンは2.8.1です.私を信じて、もしあなたのプロジェクトの中でreact-routerの前のバージョンを使っていたら、新しいバージョンは非常に大きな変更なので、更新するなら、仕事量は小さくありません.この文章はバージョンの変化を議論しないで、React-router 4.0の使い方とソースコードを議論するだけです.ソースコードはこちらです.https://github.com/ReactTraining/react-router
1.準備
あなたのreact appにパッケージyarn add react-routerを導入するだけです.dom@next注意:react-router-domはreact-routerにいくつかの小さなアップグレードを行ったライブラリで、コードはreact-routerに基づいています.
2.使用
例を直接示します.
以前のバージョンと同じように、Routerというコンポーネントはコンテナですが、その役割が変わり、4.0のRouterの下に任意のラベルを置くことができます.これは、reduxのproviderに似ていることを意味します.上記の例を通じて、あなたも具体的な変化を見ることができると信じています.実際のルーティングはRouteによって定義されます.Linkタグは現在も変化していないように見えますが、aタグと理解できます.クリックするとブラウザUrlのhash値が変わり、Routeタグでこのurlをキャプチャし、component属性で定義されたコンポーネントに戻ります.「/」に書かれたルーティングにexactキーワードがあります.このキーワードは「/」を一意に一致させます.そうしないと、「/」と「/xxx」はpathが「/」に一致します.のルーティングは、exactを作成すると、「/page 1」が「/」に一致しません.分からないなら、やってみてください.
Routeルーティングのコンポーネントを使用すると、いくつかのデータを含むオブジェクトであるmatchパラメータが得られます. isExact:さっきこのキーワードを言ったが、全等マッチングのために と表示されている. params:pathに含まれる追加データ path:Routeコンポーネントpathプロパティの値 url:実際のurlのhash値 先ほどのPage 2コンポーネントを実装します.
簡単ですから、やってみてください.注意しなければならないのは、Routeのpathの「:」の後の部分だけがワイルドカードに相当し、一致したurlは一致した部分をmatch.paramの属性としてコンポーネントに渡し、属性名はコロン後の文字列である.
3.Routerラベル
上の例で私のimportのRouterがBrowserRouterであることに細心の友人は気づいたに違いない.これは何だろうか.古いバージョンのreact-routerを使ったことがあるなら、historyを知っているに違いありません.historyは異なるブラウザまたは環境での履歴管理を互換化するために使用され、ブラウザの後退ボタンをジャンプまたはクリックすると、historyはこれらの変化を記録しなければならないが、前のreact-routerはhistoryを3つに分類した. hashHistory旧バージョンブラウザのhistory browserHistory h 5のhistory memoryHistory node環境下のhistory、memoryに格納 4.0以前のバージョンのreact-routerでは、createHashHistory、createBrowserHistory、create MemoryHistoryの3つの方法で3つの場合のhistoryを作成しました.ここでは、彼らの異なる処理方法については議論しません.好奇心があれば、理解してみてください.4.0バージョンになると、react-router-domに直接この3つのhistoryが内蔵されています.BrowserRouter、HashRouter、MemoryRouterの3種類のRouterを見ました.もちろん、React-routerのRouterを使用して、自分でcreateHistoryを作成してhistoryを作成して伝えることができます.
react-routerのhistoryライブラリで依然として使用されているのは https://github.com/ReactTraining/history
4.Routeタグ
例ではRouteのいくつかのpropに気づいたかもしれません exact: propType.bool path: propType.string component: propType.func render: propType.func
必須項目ではありません.pathに値が割り当てられていない場合、このRouteはデフォルトのレンダリングです.Routeの役割は、urlとRouteのpathプロパティの値が一致すると、componentのコンポーネントまたはrenderの内容がレンダリングされます.
もちろん、Routeにはいくつかの属性があります.例えば、location、strict、chilrenは自分で理解してほしいと思っています.
そういえば、Routeの内部はどのようにしてこのメカニズムを実現しているのでしょうか.マッチングの方法で実現されたに違いないと推測されますが、Routeはurlが更新されて再マッチングされレンダリングされたことをどのように知っていますか?
考えを整理すると、1つのウェブアプリケーションでurlを変えるのは2つの方法にほかならない.1つはハイパーリンクを利用してジャンプすることであり、もう1つはブラウザの前進とロールバック機能を使用することである.前者はリンクのジャンプイベントをトリガーした後にトリガーされますが、後者は?Routeは私たちが上述したhistoryのlisten法を利用してurlの変化を監視しています.新しいライブラリの導入を防ぐため、Routeの作成者はhtml 5のpopStateイベントを使用することを選択しました.ブラウザの前進または後退ボタンをクリックすると、このイベントがトリガーされます.Routeのコードを見てみましょう.
ここでは、Reactを使用したことがある場合は、RouteがコンポーネントをMountするときにpopStateイベントのリスニングを追加し、popStateイベントがトリガーされるたびにforceUpdateを使用して強制的にリフレッシュし、現在のlocation.pathnameに基づいてマッチングを行い、結果に基づいてレンダリングします.
PS:現在の最新コードでは、RouteソースコードはC o m p o n t WillReceivePropsのsetStateによって再レンダリングされているが、match属性はRouteコンポーネントのstateとして存在する.
では、この肝心なmatchPath方法はどのように実現されているのでしょうか.Routeは外部library:path-to-regexpを導入した.このpathToRegexpメソッドは、要求を満たす正規表現を返すために使用されます.例を挙げます.
詳細はこちらをご覧ください.https://github.com/pillarjs/path-to-regexp
特筆すべきはmatchPathメソッドでマッチング結果がキャッシュされており,既にマッチングされている文字列であればpathToRegexpをもう一度行う必要はない.
次のコードがわかります.
5.Link
urlを変える2つの方法を覚えていますか?もう1つ、Link、パラメータを見てみましょう.
onClickは言うまでもなく、target属性はaラベルのtarget属性であり、toはhrefに相当する.一方、replaceのジャンプを意味するリンクはhistoryの現在のurlを上書きするかどうか、trueの場合、新しいurlはhistoryの現在の値を上書きし、新しいurlを追加するのではなく、historyの現在の値を上書きします.
history.pushとhistory.replaceはpushStateメソッドとreplaceStateメソッドを使用していることに注意してください.
6.Redirect
Redirectコンポーネントを単独でもっと話したいのですが、ソースコードが面白いです.
このコンポーネントにUIがないことに簡単に気づき、renderメソッドはnullをreturnした.UIがないのになぜreact-routerの作成者がRedirectをコンポーネントに書くことを選んだのかという疑問が生じやすい.
著者の口にある「Just Components API」から原因を垣間見ることができると思います.
この文章があなたのReactアプリケーションをよりよく作成するのに役立つことを望んでいます.
転載先:https://www.cnblogs.com/zero7room/p/6908752.html
1.準備
あなたのreact appにパッケージyarn add react-routerを導入するだけです.dom@next注意:react-router-domはreact-routerにいくつかの小さなアップグレードを行ったライブラリで、コードはreact-routerに基づいています.
2.使用
例を直接示します.
import React from 'react'
import {BrowserRouter as Router,Route,Link} from 'react-router-dom' const Basic = () => ( - Home
- Page1
- Page2
)
以前のバージョンと同じように、Routerというコンポーネントはコンテナですが、その役割が変わり、4.0のRouterの下に任意のラベルを置くことができます.これは、reduxのproviderに似ていることを意味します.上記の例を通じて、あなたも具体的な変化を見ることができると信じています.実際のルーティングはRouteによって定義されます.Linkタグは現在も変化していないように見えますが、aタグと理解できます.クリックするとブラウザUrlのhash値が変わり、Routeタグでこのurlをキャプチャし、component属性で定義されたコンポーネントに戻ります.「/」に書かれたルーティングにexactキーワードがあります.このキーワードは「/」を一意に一致させます.そうしないと、「/」と「/xxx」はpathが「/」に一致します.のルーティングは、exactを作成すると、「/page 1」が「/」に一致しません.分からないなら、やってみてください.
Routeルーティングのコンポーネントを使用すると、いくつかのデータを含むオブジェクトであるmatchパラメータが得られます.
const Page2 = ({ match }) => (
Page2
-
branch1
-
branch2
-
branch3
(
Default Information
)} />
)
const Branch = ({ match }) => {
console.log(match);
return (
{match.params.branchId}
)
}
簡単ですから、やってみてください.注意しなければならないのは、Routeのpathの「:」の後の部分だけがワイルドカードに相当し、一致したurlは一致した部分をmatch.paramの属性としてコンポーネントに渡し、属性名はコロン後の文字列である.
3.Routerラベル
上の例で私のimportのRouterがBrowserRouterであることに細心の友人は気づいたに違いない.これは何だろうか.古いバージョンのreact-routerを使ったことがあるなら、historyを知っているに違いありません.historyは異なるブラウザまたは環境での履歴管理を互換化するために使用され、ブラウザの後退ボタンをジャンプまたはクリックすると、historyはこれらの変化を記録しなければならないが、前のreact-routerはhistoryを3つに分類した.
react-routerのhistoryライブラリで依然として使用されているのは https://github.com/ReactTraining/history
4.Routeタグ
例ではRouteのいくつかのpropに気づいたかもしれません
必須項目ではありません.pathに値が割り当てられていない場合、このRouteはデフォルトのレンダリングです.Routeの役割は、urlとRouteのpathプロパティの値が一致すると、componentのコンポーネントまたはrenderの内容がレンダリングされます.
もちろん、Routeにはいくつかの属性があります.例えば、location、strict、chilrenは自分で理解してほしいと思っています.
そういえば、Routeの内部はどのようにしてこのメカニズムを実現しているのでしょうか.マッチングの方法で実現されたに違いないと推測されますが、Routeはurlが更新されて再マッチングされレンダリングされたことをどのように知っていますか?
考えを整理すると、1つのウェブアプリケーションでurlを変えるのは2つの方法にほかならない.1つはハイパーリンクを利用してジャンプすることであり、もう1つはブラウザの前進とロールバック機能を使用することである.前者はリンクのジャンプイベントをトリガーした後にトリガーされますが、後者は?Routeは私たちが上述したhistoryのlisten法を利用してurlの変化を監視しています.新しいライブラリの導入を防ぐため、Routeの作成者はhtml 5のpopStateイベントを使用することを選択しました.ブラウザの前進または後退ボタンをクリックすると、このイベントがトリガーされます.Routeのコードを見てみましょう.
class Route extends Component { static propTypes: { path: PropTypes.string, exact: PropTypes.bool, component: PropTypes.func, render: PropTypes.func, } componentWillMount() { addEventListener("popstate", this.handlePop) } componentWillUnmount() { removeEventListener("popstate", this.handlePop) } handlePop = () => { this.forceUpdate() } render() { const { path, exact, component, render, } = this.props //location const match = matchPath(location.pathname, { path, exact }) return ( // ,component component ? ( match ? React.createElement(component, props) : null ) : render ? ( // render prop is next, only called if there's a match match ? render(props) : null ) : children ? ( // children come last, always called typeof children === 'function' ? ( children(props) ) : !Array.isArray(children) || children.length ? ( // Preact defaults to empty children array React.Children.only(children) ) : ( null ) ) : ( null ) ) } }
ここでは、Reactを使用したことがある場合は、RouteがコンポーネントをMountするときにpopStateイベントのリスニングを追加し、popStateイベントがトリガーされるたびにforceUpdateを使用して強制的にリフレッシュし、現在のlocation.pathnameに基づいてマッチングを行い、結果に基づいてレンダリングします.
PS:現在の最新コードでは、RouteソースコードはC o m p o n t WillReceivePropsのsetStateによって再レンダリングされているが、match属性はRouteコンポーネントのstateとして存在する.
では、この肝心なmatchPath方法はどのように実現されているのでしょうか.Routeは外部library:path-to-regexpを導入した.このpathToRegexpメソッドは、要求を満たす正規表現を返すために使用されます.例を挙げます.
let keys = [],keys2=[]
let re = pathToRegexp('/foo/:bar', keys)
//re = /^\/foo\/([^\/]+?)\/?$/i keys = [{ name: 'bar', prefix: '/', delimiter: '/', optional: false, repeat: false, pattern: '[^\\/]+?' }] let re2 = pathToRegexp('/foo/bar', keys2) //re2 = /^\/foo\/bar(?:\/(?=$))?$/i keys2 = []
詳細はこちらをご覧ください.https://github.com/pillarjs/path-to-regexp
特筆すべきはmatchPathメソッドでマッチング結果がキャッシュされており,既にマッチングされている文字列であればpathToRegexpをもう一度行う必要はない.
次のコードがわかります.
const match = re.exec(pathname)
if (!match)
return null const [ url, ...values ] = match const isExact = pathname === url // exact true, pathname===url if (exact && !isExact) return null return { path, url: path === '/' && url === '' ? '/' : url, isExact, params: keys.reduce((memo, key, index) => { memo[key.name] = values[index] return memo }, {}) }
5.Link
urlを変える2つの方法を覚えていますか?もう1つ、Link、パラメータを見てみましょう.
static propTypes = {
onClick: PropTypes.func,
target: PropTypes.string,
replace: PropTypes.bool, to: PropTypes.oneOfType([ PropTypes.string, PropTypes.object ]).isRequired }
onClickは言うまでもなく、target属性はaラベルのtarget属性であり、toはhrefに相当する.一方、replaceのジャンプを意味するリンクはhistoryの現在のurlを上書きするかどうか、trueの場合、新しいurlはhistoryの現在の値を上書きし、新しいurlを追加するのではなく、historyの現在の値を上書きします.
handleClick = (event) => {
if (this.props.onClick) this.props.onClick(event) if ( !event.defaultPrevented && // event.button === 0 && // !this.props.target && // !isModifiedEvent(event) // key , ctrl、shift、alt、meta ) { event.preventDefault() const { history } = this.context.router const { replace, to } = this.props if (replace) { history.replace(to) } else { history.push(to) } } }
history.pushとhistory.replaceはpushStateメソッドとreplaceStateメソッドを使用していることに注意してください.
6.Redirect
Redirectコンポーネントを単独でもっと話したいのですが、ソースコードが面白いです.
class Redirect extends React.Component { //... isStatic() { return this.context.router && this.context.router.staticContext } componentWillMount() { if (this.isStatic()) this.perform() } componentDidMount() { if (!this.isStatic()) this.perform() } perform() { const { history } = this.context.router const { push, to } = this.props if (push) { history.push(to) } else { history.replace(to) } } render() { return null } }
このコンポーネントにUIがないことに簡単に気づき、renderメソッドはnullをreturnした.UIがないのになぜreact-routerの作成者がRedirectをコンポーネントに書くことを選んだのかという疑問が生じやすい.
著者の口にある「Just Components API」から原因を垣間見ることができると思います.
この文章があなたのReactアプリケーションをよりよく作成するのに役立つことを望んでいます.
転載先:https://www.cnblogs.com/zero7room/p/6908752.html