React の高次コンポーネントとは何ですか? React の上位コンポーネントを使用してブレッドクラム ナビゲーションを作成する方法について説明します。
React 上位コンポーネントは、フォーム内で変更が必要な React コンポーネントをラップしますの高階関数を呼び出し、処理が完了したら React コンポーネントを返します。 React の上位コンポーネントは、#react-router の
withRouter や
react-redux## の connect
など、React エコシステムで非常に頻繁に使用されます。 # 多くの API はこの方法で実装されています。
のルーティング テーブルから取得できるため、ここからブレッドクラムの上位コンポーネントの実装を開始できます。ナビゲーション。 まず、ルーティング テーブルによって提供されるデータと、ターゲットのブレッドクラム コンポーネントに必要なデータを見てみましょう。
// 这里展示的是 react-router4 的route示例 let routes = [ { breadcrumb: '一级目录', path: '/a', component: require('../a/index.js').default, items: [ { breadcrumb: '二级目录', path: '/a/b', component: require('../a/b/index.js').default, items: [ { breadcrumb: '三级目录1', path: '/a/b/c1', component: require('../a/b/c1/index.js').default, exact: true, }, { breadcrumb: '三级目录2', path: '/a/b/c2', component: require('../a/b/c2/index.js').default, exact: true, }, } ] } ] // 理想中的面包屑组件 // 展示格式为 a / b / c1 并都附上链接 const BreadcrumbsComponent = ({ breadcrumbs }) => ( <div> {breadcrumbs.map((breadcrumb, index) => ( <span key={breadcrumb.props.path}> <link to={breadcrumb.props.path}>{breadcrumb}</link> {index < breadcrumbs.length - 1 && <i> / </i>} </span> ))} </div> );
ここでは、ルーティング テーブルが提供するデータには 3 種類あることがわかります。ブレッドクラム コンポーネントは、現在のページのパス、ブレッドクラムに含まれるテキスト、ブレッドクラムのナビゲーション リンクを提供する必要があります。
まず、react-router が提供する withRouter 上位コンポーネント パッケージを使用します。これにより、サブコンポーネントが現在のページの location 属性を取得し、それによってページ パスを取得できるようになります。
後者の 2 つは、ルートを操作する必要があります。まず、ルートによって提供されるデータをブレッドクラム ナビゲーションに必要な形式にフラット化します。関数を使用してそれを実装できます。
/** * 以递归的方式展平react router数组 */ const flattenRoutes = arr => arr.reduce(function(prev, item) { prev.push(item); return prev.concat( Array.isArray(item.items) ? flattenRoutes(item.items) : item ); }, []);
次に、フラット化されたディレクトリ パス マッピングと現在のページ パスを処理関数に入力して、ブレッドクラム ナビゲーション構造を生成します。
export const getBreadcrumbs = ({ flattenRoutes, location }) => { // 初始化匹配数组match let matches = []; location.pathname // 取得路径名,然后将路径分割成每一路由部分. .split('?')[0] .split('/') // 对每一部分执行一次调用`getBreadcrumb()`的reduce. .reduce((prev, curSection) => { // 将最后一个路由部分与当前部分合并,比如当路径为 `/x/xx/xxx` 时,pathSection分别检查 `/x` `/x/xx` `/x/xx/xxx` 的匹配,并分别生成面包屑 const pathSection = `${prev}/${curSection}`; const breadcrumb = getBreadcrumb({ flattenRoutes, curSection, pathSection, }); // 将面包屑导入到matches数组中 matches.push(breadcrumb); // 传递给下一次reduce的路径部分 return pathSection; }); return matches; };
次に、パンくずリストのパス部分ごとにディレクトリ名を生成し、対応するルーティングの場所を指すリンク属性を付加します。
const getBreadcrumb = ({ flattenRoutes, curSection, pathSection }) => { const matchRoute = flattenRoutes.find(ele => { const { breadcrumb, path } = ele; if (!breadcrumb || !path) { throw new Error( 'Router中的每一个route必须包含 `path` 以及 `breadcrumb` 属性' ); } // 查找是否有匹配 // exact 为 react router4 的属性,用于精确匹配路由 return matchPath(pathSection, { path, exact: true }); }); // 返回breadcrumb的值,没有就返回原匹配子路径名 if (matchRoute) { return render({ content: matchRoute.breadcrumb || curSection, path: matchRoute.path, }); } // 对于routes表中不存在的路径 // 根目录默认名称为首页. return render({ content: pathSection === '/' ? '首页' : curSection, path: pathSection, }); };
次に、render 関数が最終的な単一のブレッドクラム ナビゲーション スタイルを生成します。単一のブレッドクラム コンポーネントは、ブレッドクラムが指すパス
path とブレッドクラム コンテンツ マッピング content
の 2 つのプロパティをレンダー関数に提供する必要があります。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">/**
*
*/
const render = ({ content, path }) => {
const componentProps = { path };
if (typeof content === 'function') {
return <content {...componentProps} />;
}
return <span {...componentProps}>{content}</span>;
};</pre><div class="contentsignin">ログイン後にコピー</div></div>
これらの関数を使用すると、現在のパスとルーティング属性をラップされたコンポーネントに渡すことができる React の上位コンポーネントを実装できます。コンポーネントを渡して、新しい同一のコンポーネント構造を返すことで、コンポーネントの外部の機能や操作が損なわれることはありません。
const BreadcrumbsHoc = ( location = window.location, routes = [] ) => Component => { const BreadComponent = ( <Component breadcrumbs={getBreadcrumbs({ flattenRoutes: flattenRoutes(routes), location, })} /> ); return BreadComponent; }; export default BreadcrumbsHoc;
この上位コンポーネントを呼び出す方法も非常に簡単で、現在のパスと
react ルーター#全体によって生成されたroutes 属性を渡すだけです。 ##。
現在のパスの取得方法は、react router
が提供する
withRouter 関数を利用することができますので、使用方法については関連ドキュメントを参照してください。
withRouter
自体は、ラップされたコンポーネントの
location 属性を含むいくつかのルーティング属性を提供できる上位コンポーネントであることに言及する価値があります。したがって、この API は、高次コンポーネントを学習するための優れたリファレンスとしても使用できます。
withRouter(({ location }) => BreadcrumbsHoc(location, routes)(BreadcrumbsComponent) );
Q&A
routes が独自に手動で保守されていない場合、ローカルに存在しますが、リクエストを通じてプルされ、redux に保存されます。
react-redux によって提供される
connect 高階関数を通じてラップされると、ルートによってパッケージが変更されることはありません. クラムコンポーネントが更新されました。使用法は次のとおりです。
function mapStateToProps(state) { return { routes: state.routes, }; } connect(mapStateToProps)( withRouter(({ location }) => BreadcrumbsHoc(location, routes)(BreadcrumbsComponent) ) );
bug です。 React-redux の接続上位コンポーネントは、受信パラメータ コンポーネントの shouldComponentUpdate フック関数を実装するため、更新関連のライフ サイクル関数 (レンダリングを含む) は、プロップが変更された場合にのみトリガーされます
、そして明らかに、 location オブジェクトはパラメータ コンポーネントに prop として渡されません。 公式に推奨されるアプローチは、withRouter を使用して
の 戻り値
、つまり をラップすることです。<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">withRouter(
connect(mapStateToProps)(({ location, routes }) =>
BreadcrumbsHoc(location, routes)(BreadcrumbsComponent)
)
);</pre><div class="contentsignin">ログイン後にコピー</div></div>
<p>其实我们从这里也可以看出,高阶组件同高阶函数一样,不会对组件的类型造成任何更改,因此高阶组件就如同链式调用一样,可以任意多层包裹来给组件传入不同的属性,在正常情况下也可以随意调换位置,在使用上非常的灵活。这种可插拔特性使得高阶组件非常受React生态的青睐,很多开源库里都能看到这种特性的影子,有空也可以都拿出来分析一下。</p>
以上がReact の高次コンポーネントとは何ですか?ブレッドクラムナビゲーションはどのように作成されるのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。