{"id":14582,"date":"2017-12-01T09:00:01","date_gmt":"2017-12-01T00:00:01","guid":{"rendered":"http:\/\/www.techscore.com\/blog\/?p=14582"},"modified":"2018-11-14T16:33:42","modified_gmt":"2018-11-14T07:33:42","slug":"where_does_react-router-history_come_from","status":"publish","type":"post","link":"https:\/\/www.techscore.com\/blog\/2017\/12\/01\/where_does_react-router-history_come_from\/","title":{"rendered":"React Router\u306ehistory\u306f\u3069\u3053\u304b\u3089\u6765\u308b\u306e\u304b"},"content":{"rendered":"<p>\u3053\u308c\u306f <a href=\"\/blog\/2017\/11\/28\/techscore-advent-calendar-2017\/\">TECHSCORE Advent Calendar 2017<\/a> \u306e1\u65e5\u76ee\u306e\u8a18\u4e8b\u3067\u3059\u3002<\/p>\n<p>SPA(SinglePageApplication)\u3092\u4f5c\u6210\u3059\u308b\u969b\u306b\u306f\u907f\u3051\u3066\u306f\u901a\u308c\u306a\u3044\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u3002<br \/>\nReact\u3067\u306f<a href=\"https:\/\/reacttraining.com\/react-router\/\">React Router<\/a>\u3092\u4f7f\u3046\u3053\u3068\u3067\u3001\u7c21\u5358\u306b\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u3092\u5b9f\u73fe\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u308b\u306e\u3067\u3059\u304c\u3001\u753b\u9762\u9077\u79fb\u306b\u4f7f\u7528\u3059\u308bhistory\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u4f7f\u3044\u65b9\u304c\u521d\u898b\u3067\u306f\u5c11\u3057\u96e3\u3057\u3044\u3088\u3046\u306b\u611f\u3058\u307e\u3059\u3002<\/p>\n<p>\u3053\u3053\u3067\u306f\u3001React Router\u306e\u5b9f\u88c5\u3092\u898b\u306a\u304c\u3089\u3001history\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306b\u3064\u3044\u3066\u63a2\u3063\u3066\u3044\u304d\u307e\u3059\u3002<br \/>\n\u306a\u304a\u3001\u73fe\u6642\u70b9\u3067\u6700\u65b0\u306e<a href=\"https:\/\/github.com\/ReactTraining\/react-router\/tree\/v4.2.2\">v4.2.2<\/a>\u306e\u5b9f\u88c5\u3092\u53c2\u7167\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n<div style=\"\nmargin-left: 20px;\npadding: 0 8px 0 8px;\nborder-style: solid;\nborder-color: #d0d0d0;\nborder-width: 2px;\nborder-radius: 8px;\n\"><\/p>\n<h3>\u305d\u306e\u524d\u306b<\/h3>\n<p>React Router\u3092\u4f7f\u3046\u5834\u5408\u3001\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u300cBrowserRouter\u3092Router\u3068\u3057\u3066import\u3059\u308b\u300d\u3053\u3068\u304c\u591a\u3044\u3088\u3046\u3067\u3059\u3002<a href=\"https:\/\/reacttraining.com\/react-router\/web\/example\/basic\">React Router\u306eEXAMPLES<\/a>\u3067\u3082\u305d\u3046\u306a\u3063\u3066\u3044\u307e\u3059\u3002<\/p>\n<pre class=\"lang:js decode:true \" >\r\nimport { BrowserRouter as Router, ... } from 'react-router-dom';\r\n\r\nconst App = () =>\r\n  <Router>\r\n     ...\r\n  <\/Router>;\r\n<\/pre>\n<p>\u4e00\u65b9\u3001React Router\u5185\u90e8\u3067<a href=\"https:\/\/github.com\/ReactTraining\/react-router\/blob\/v4.2.2\/packages\/react-router\/modules\/Router.js\">Router<\/a>\u3068\u3044\u3046\u540d\u79f0\u306e\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u304c\u5b9a\u7fa9\u3055\u308c\u3066\u304a\u308a\u3001\u4ee5\u4e0b\u306e\u6587\u7ae0\u3067\u306f\u3053\u306eRouter\u306b\u8a00\u53ca\u3057\u3066\u3044\u307e\u3059\u3002\u4ee5\u4e0b\u306e\u30b5\u30f3\u30d7\u30eb\u3067\u306f\u3001BrowserRouter\u3068Router\u306e\u533a\u5225\u304c\u660e\u78ba\u306b\u306a\u308b\u3088\u3046\u306bBrowserRouter\u3092\u305d\u306e\u307e\u307eimport\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n<pre class=\"lang:js decode:true \" >\r\nimport { BrowserRouter, ... } from 'react-router-dom';\r\n\r\nconst App = () =>\r\n  <BrowserRouter>\r\n     ...\r\n  <\/BrowserRouter>;\r\n<\/pre>\n<\/div>\n<h2>\u57fa\u672c\u7684\u306ahistory\u306e\u4f7f\u3044\u65b9<\/h2>\n<p>\u307e\u305a\u306f\u3058\u3081\u306b\u57fa\u672c\u7684\u306a\u4f7f\u3044\u65b9\u3092\u78ba\u8a8d\u3059\u308b\u305f\u3081\u3001history\u3092\u4f7f\u3063\u305f\u5358\u7d14\u306a\u30a2\u30d7\u30ea\u3092\u4f5c\u3063\u3066\u307f\u307e\u3059\u3002<a href=\"https:\/\/stackblitz.com\/edit\/react-8ngh2p?file=index.js\">\u52d5\u4f5c\u3059\u308b\u30b5\u30f3\u30d7\u30eb\u306f\u3053\u3061\u3089<\/a>\u3002<\/p>\n<pre class=\"lang:js start-line:6 decode:true \" >\r\nconst App = () =>\r\n  <BrowserRouter>\r\n    <div>\r\n      <Route exact path=\"\/\" component={Home} \/>\r\n      <Route path=\"\/foo\" component={Foo} \/>\r\n    <\/div>\r\n  <\/BrowserRouter>;\r\n\r\nconst Home = () => <Link to=\"\/foo\">foo<\/Link>;\r\n\r\nconst Foo = (props) =>\r\n  <div>\r\n    <button onClick={() => props.history.goBack()}>\r\n      Foo: back OK\r\n    <\/button><br \/>\r\n    <Bar \/><br \/>\r\n    <Baz history={props.history} \/><br \/>\r\n    <Qux \/><br \/>\r\n  <\/div>;\r\n\r\nconst Bar = (props) =>\r\n  <button onClick={() => props.history.goBack()}>\r\n    Bar: back NG\r\n  <\/button>;\r\n\r\nconst Baz = (props) =>\r\n  <button onClick={() => props.history.goBack()}>\r\n    Baz: back OK\r\n  <\/button>;\r\n\r\nconst Qux = withRouter(\r\n  (props) =>\r\n    <button onClick={() => props.history.goBack()}>\r\n      Qux: back OK\r\n    <\/button>\r\n);\r\n<\/pre>\n<p>\u6700\u521d\u306e\u753b\u9762(&lt;Home&gt;)\u306b\u306f\u30ea\u30f3\u30af\u304c\u4e00\u3064\u3042\u308a\u3001\u305d\u306e\u30ea\u30f3\u30af\u3092\u30af\u30ea\u30c3\u30af\u3059\u308b\u3068\u5225\u306e\u753b\u9762(&lt;Foo&gt;)\u306b\u9077\u79fb\u3057\u307e\u3059\u3002&lt;Foo&gt;\u753b\u9762\u306b\u306f\u300cback\u300d\u30dc\u30bf\u30f3\u304c\uff14\u3064\u3042\u308a\u3001\u305d\u308c\u305e\u308c<\/p>\n<pre class=\"lang:js decode:true inline:true \">history.goBack()<\/pre>\n<p>\u3067\u524d\u306e\u753b\u9762(&lt;Home&gt;)\u306b\u623b\u308b\u3068\u3044\u3046\u60f3\u5b9a\u3067\u3059\u3002<\/p>\n<ul>\n<li>&lt;Route&gt;\u306ecomponent\u5c5e\u6027\u306b\u6307\u5b9a\u3057\u305f\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8(&lt;Foo&gt;)\u3067\u306f\u3001props\u304b\u3089history\u3092\u53d6\u5f97\u3057\u3066\u4f7f\u7528\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/li>\n<li>\u4e00\u65b9\u3001&lt;Foo&gt;\u306e\u5b50\u8981\u7d20\u3067\u3042\u308b&lt;Bar&gt;\u3067\u306fprops\u306bhistory\u306f\u542b\u307e\u308c\u3066\u3044\u307e\u305b\u3093\u306e\u3067\u3001\u30dc\u30bf\u30f3\u3092\u30af\u30ea\u30c3\u30af\u3059\u308b\u3068\u30a8\u30e9\u30fc\u306b\u306a\u308a\u307e\u3059\u3002<\/li>\n<li>&lt;Foo&gt;\u306e\u5b50\u8981\u7d20\u3067\u3082\u3001\u5c5e\u6027\u306bhistory\u3092\u6307\u5b9a\u3057\u3066props\u7d4c\u7531\u3067\u53d7\u3051\u53d6\u308c\u3070\u3001history\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\uff08&lt;Baz&gt;)\u3002<\/li>\n<li>&lt;Qux&gt;\u306e\u3088\u3046\u306bwithRouter()\u3092\u4f7f\u3046\u3053\u3068\u3067\u3001&lt;Foo&gt;\u306e\u5b50\u8981\u7d20\u3067\u3082history\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/li>\n<\/ul>\n<h2>history\u306f\u3069\u3053\u304b\u3089\u6765\u308b\u306e\u304b<\/h2>\n<p>\u6b21\u306b\u3053\u306ehistory\u306f\u3069\u3053\u3067\u4f5c\u3089\u308c\u3001\u3069\u306e\u3088\u3046\u306b&lt;Foo&gt;\u306eprops\u306b\u6e21\u3055\u308c\u308b\u306e\u304b\u3001React Router\u306e\u5b9f\u88c5\u3092\u898b\u306a\u304c\u3089\u63a2\u3063\u3066\u3044\u304d\u307e\u3059\u3002<br \/>\n\u307e\u305a&lt;Route&gt;\u306e\u5b9f\u88c5\u306e\u3046\u3061\u3001<a href=\"https:\/\/github.com\/ReactTraining\/react-router\/blob\/v4.2.2\/packages\/react-router\/modules\/Route.js#L105-L130\">render()<\/a>\u306b\u6ce8\u76ee\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"lang:js start-line:105 mark:4,6,10 decode:true \" >\r\n  render() {\r\n    const { match } = this.state\r\n    const { children, component, render } = this.props\r\n    const { history, route, staticContext } = this.context.router\r\n    const location = this.props.location || route.location\r\n    const props = { match, location, history, staticContext }\r\n\r\n    return (\r\n      component ? ( \/\/ component prop gets first priority, only called if there's a match\r\n        match ? React.createElement(component, props) : null\r\n      ) : render ? ( \/\/ render prop is next, only called if there's a match\r\n        match ? render(props) : null\r\n      ) : children ? ( \/\/ children come last, always called\r\n        typeof children === 'function' ? (\r\n          children(props)\r\n        ) : !isEmptyChildren(children) ? (\r\n          React.Children.only(children)\r\n        ) : (\r\n          null\r\n        )\r\n      ) : (\r\n        null\r\n      )\r\n    )\r\n  }\r\n<\/pre>\n<p>114\u884c\u76ee\u3067component\u5c5e\u6027\u306b\u6307\u5b9a\u3055\u308c\u305f\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u306bprops\u3092\u6e21\u3057\u3066\u3044\u307e\u3059\u3002\u3053\u3053\u3067history\u304c\u6e21\u3063\u3066\u3044\u308b\u306e\u3067\u3057\u3087\u3046\u3002<br \/>\n108\u884c\u76ee\u3068110\u884c\u76ee\u304b\u3089\u306f\u3001context\u304b\u3089\u53d6\u308a\u51fa\u3057\u305fhistory\u3092props\u306b\u8a2d\u5b9a\u3057\u3066\u3044\u308b\u306e\u304c\u308f\u304b\u308a\u307e\u3059\u3002<\/p>\n<div style=\"\nmargin-left: 20px;\npadding: 0 8px 0 8px;\nborder-style: solid;\nborder-color: #d0d0d0;\nborder-width: 2px;\nborder-radius: 8px;\n\"><\/p>\n<h3>context<\/h3>\n<p>context\u3068\u306fReact\u306e\u6a5f\u80fd\u3067\u3001props\u306e\u30d0\u30b1\u30c4\u30ea\u30ec\u30fc\u3092\u305b\u305a\u306b\u30c7\u30fc\u30bf\u3092\u4e0b\u4f4d\u306e\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u3078\u3068\u6e21\u3057\u3066\u3044\u304f\u4ed5\u7d44\u307f\u3067\u3059\u3002<br \/>\n<a href=\"https:\/\/reactjs.org\/docs\/context.html\">Context<\/a><\/p>\n<blockquote><p>\nIn some cases, you want to pass data through the component tree without having to pass the props down manually at every level. You can do this directly in React with the powerful \"context\" API.\n<\/p><\/blockquote>\n<p><a href=\"https:\/\/reactjs.org\/docs\/context.html#how-to-use-context\">How To Use Context<\/a><\/p>\n<blockquote><p>\nBy adding childContextTypes and getChildContext to MessageList (the context provider), React passes the information down automatically and any component in the subtree (in this case, Button) can access it by defining contextTypes.\n<\/p><\/blockquote>\n<p>\u4e0a\u4f4d\u306e\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u3067childContextTypes\u3068getChildContext()\u3092\u5b9a\u7fa9\u3057\u3001\u4e0b\u4f4d\u306e\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u3067contextTypes\u3092\u5b9a\u7fa9\u3059\u308b\u3053\u3068\u3067\u3001context\u3092\u53d7\u3051\u6e21\u3059\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n<blockquote><p>\nthe powerful \"context\" API\n<\/p><\/blockquote>\n<p>\u5f37\u529b\u306aAPI\u306a\u3093\u3067\u3059\u304c\u3001<br \/>\n<a href=\"https:\/\/reactjs.org\/docs\/context.html#why-not-to-use-context\">Why Not To Use Context<\/a><\/p>\n<blockquote><p>\nIf you want your application to be stable, don\u2019t use context. It is an experimental API and it is likely to break in future releases of React.\n<\/p><\/blockquote>\n<p>\u300c\u5b9f\u9a13\u7684\u3067\u5c06\u6765\u5909\u308f\u308b\u304b\u3082\u3057\u308c\u306a\u3044\u306e\u3067\u3001\u4f7f\u308f\u306a\u3044\u307b\u3046\u304c\u3044\u3044\u3088\u300d\u3068\u3082\u66f8\u3044\u3066\u3042\u308a\u307e\u3059\u3002<\/p><\/div>\n<p>&lt;Route&gt;\u306e\u5b9f\u88c5\u306e<a href=\"https:\/\/github.com\/ReactTraining\/react-router\/blob\/v4.2.2\/packages\/react-router\/modules\/Route.js#L29-L35\">29\u301c35\u884c\u76ee<\/a>\u3067contextTypes\u3092\u5b9a\u7fa9\u3057\u3066\u3001context\u3092\u53d7\u3051\u53d6\u3063\u3066\u3044\u307e\u3059\u3002<\/p>\n<pre class=\"lang:js start-line:29 decode:true \" >\r\n  static contextTypes = {\r\n    router: PropTypes.shape({\r\n      history: PropTypes.object.isRequired,\r\n      route: PropTypes.object.isRequired,\r\n      staticContext: PropTypes.object\r\n    })\r\n  }\r\n<\/pre>\n<p>\u3055\u3066\u3001&lt;Route&gt;\u3067context\u3092\u53d7\u3051\u53d6\u3063\u3066\u3044\u308b\u3068\u3044\u3046\u3053\u3068\u306f\u3001\u4e0a\u4f4d\u306e\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u3067context\u3092\u8a2d\u5b9a\u3057\u3066\u3044\u308b\u306f\u305a\u3067\u3059\u3002<a href=\"https:\/\/stackblitz.com\/edit\/react-8ngh2p?file=index.js\">\u524d\u8ff0\u306e\u30b5\u30f3\u30d7\u30eb<\/a>\u3060\u3068\u3001&lt;Route&gt;\u306e\u4e0a\u4f4d\u306e\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u306f&lt;BrowserRouter&gt;\u3057\u304b\u3042\u308a\u307e\u305b\u3093\u306e\u3067\u3001<a href=\"https:\/\/github.com\/ReactTraining\/react-router\/blob\/v4.2.2\/packages\/react-router-dom\/modules\/BrowserRouter.js\">&lt;BrowserRouter&gt;\u306e\u5b9f\u88c5<\/a>\u3092\u898b\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n<pre class=\"lang:js start-line:10 mark:10,21 decode:true \" >\r\nclass BrowserRouter extends React.Component {\r\n  static propTypes = {\r\n    basename: PropTypes.string,\r\n    forceRefresh: PropTypes.bool,\r\n    getUserConfirmation: PropTypes.func,\r\n    keyLength: PropTypes.number,\r\n    children: PropTypes.node\r\n  }\r\n\r\n  history = createHistory(this.props)\r\n\r\n  componentWillMount() {\r\n    warning(\r\n      !this.props.history,\r\n      '<BrowserRouter> ignores the history prop. To use a custom history, ' +\r\n      'use `import { Router }` instead of `import { BrowserRouter as Router }`.'\r\n    )\r\n  }\r\n\r\n  render() {\r\n    return <Router history={this.history} children={this.props.children}\/>\r\n  }\r\n}\r\n<\/pre>\n<p>19\u884c\u76ee\u3067history\u3092\u4f5c\u6210\u3057\u3066\u3001<br \/>\n30\u884c\u76ee\u3067&lt;Router&gt;\u306b\u6e21\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n<p>&lt;Router&gt;\u306e\u5b9f\u88c5\u3067\u306f\u3001<a href=\"https:\/\/github.com\/ReactTraining\/react-router\/blob\/v4.2.2\/packages\/react-router\/modules\/Router.js#L19-L34\">19\u301c34\u884c\u76ee<\/a>\u3067history\u3092\u542b\u3093\u3060\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3092context\u306b\u8a2d\u5b9a\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n<pre class=\"lang:js start-line:19 decode:true \" >\r\n  static childContextTypes = {\r\n    router: PropTypes.object.isRequired\r\n  }\r\n\r\n  getChildContext() {\r\n    return {\r\n      router: {\r\n        ...this.context.router,\r\n        history: this.props.history,\r\n        route: {\r\n          location: this.props.history.location,\r\n          match: this.state.match\r\n        }\r\n      }\r\n    }\r\n  }\r\n<\/pre>\n<p>history\u306e\u751f\u6210\u3001\u53d7\u3051\u6e21\u3057\u306e\u6d41\u308c\u3092\u56f3\u306b\u8868\u3059\u3068\u3053\u3093\u306a\u611f\u3058\u3067\u3057\u3087\u3046\u304b\u3002context\u3092\u7d4c\u7531\u3059\u308b\u3053\u3068\u3067\u76f4\u63a5\u95a2\u4fc2\u306e\u306a\u3044\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u306bhistory\u3092\u6e21\u3057\u3066\u3044\u307e\u3059\u3002<br \/>\n<a href=\"https:\/\/www.techscore.com\/blog\/wp\/wp-content\/uploads\/2017\/11\/history.png\" rel=\"facebox\" rel=\"attachment wp-att-14670\"><img loading=\"lazy\" src=\"https:\/\/www.techscore.com\/blog\/wp\/wp-content\/uploads\/2017\/11\/history-300x300.png\" alt=\"\" width=\"300\" height=\"300\" class=\"aligncenter size-medium wp-image-14670\" srcset=\"https:\/\/www.techscore.com\/blog\/wp\/wp-content\/uploads\/2017\/11\/history-300x300.png 300w, https:\/\/www.techscore.com\/blog\/wp\/wp-content\/uploads\/2017\/11\/history-150x150.png 150w, https:\/\/www.techscore.com\/blog\/wp\/wp-content\/uploads\/2017\/11\/history.png 400w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<h2>\u3010\u975e\u63a8\u5968\u3011context\u7d4c\u7531\u3067history\u3092\u53d7\u3051\u53d6\u3063\u305f\u3089\u3044\u3044\u306e\u3067\u306f\uff1f<\/h2>\n<p>&lt;BrowserRouter&gt;\u3067\u751f\u6210\u3055\u308c\u305fhistory\u3092context\u7d4c\u7531\u3067&ltRouter&gt\u306b\u53d7\u3051\u6e21\u3057\u3066\u3044\u308b\u3053\u3068\u304c\u308f\u304b\u308a\u307e\u3057\u305f\u3002\u3068\u3044\u3046\u3053\u3068\u306f\u3001<a href=\"https:\/\/stackblitz.com\/edit\/react-8ngh2p?file=index.js\">\u524d\u8ff0\u306e\u30b5\u30f3\u30d7\u30eb<\/a>\u3067history\u304c\u4f7f\u3048\u306a\u304b\u3063\u305f&lt;Foo&gt;\u306e\u5b50\u8981\u7d20\u3067\u3082\u3001\u540c\u3058\u3088\u3046\u306b\u3059\u308c\u3070history\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u308b\u306e\u3067\u306f\u306a\u3044\u3067\u3057\u3087\u3046\u304b\u3002<a href=\"https:\/\/stackblitz.com\/edit\/react-vlqzp8?file=index.js\">\u7c21\u5358\u306b\u3067\u304d\u307e\u3057\u305f\u3002<\/a><\/p>\n<p>\u4ee5\u4e0b\u306e\u5b9f\u88c5\u3092\u524d\u8ff0\u306e\u30b5\u30f3\u30d7\u30eb\u306b\u8ffd\u8a18\u3057\u3066\u3044\u307e\u3059\u3002<br \/>\n49\u301c55\u884c\u76ee\u306bcontext\u3092\u53d7\u3051\u53d6\u308b\u5b9a\u7fa9\u3092\u8a18\u8ff0\u3057\u3066\u3044\u307e\u3059\u3002<br \/>\n44\u884c\u76ee\u3067component function\u306e\u7b2c2\u5f15\u6570\u3068\u3057\u3066context\u3092\u53d7\u3051\u53d6\u308a\u3001<br \/>\n45\u884c\u76ee\u3067context.router\u304b\u3089history\u3092\u53d6\u308a\u51fa\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n<pre class=\"lang:js start-line:44 mark:1,2,6-12 decode:true \" >\r\nconst Quux = (props, context) =>\r\n  <button onClick={() => context.router.history.goBack()}>\r\n    Quux: back OK\r\n  <\/button>;\r\n\r\nQuux.contextTypes = {\r\n  router: PropTypes.shape({\r\n    history: PropTypes.object.isRequired,\r\n    route: PropTypes.object.isRequired,\r\n    staticContext: PropTypes.object\r\n  })\r\n};\r\n<\/pre>\n<p>\u524d\u8ff0\u306e\u30b5\u30f3\u30d7\u30eb\u3067history\u304c\u4f7f\u3048\u306a\u304b\u3063\u305f&lt;Bar&gt;(21\u884c\u76ee)\u3068\u540c\u3058\u65b9\u6cd5\u3067\u3001\u65b0\u3057\u304f\u4f5c\u3063\u305f&lt;Quux&gt;\u3092\u914d\u7f6e\u3057\u3066\u3044\u307e\u3059(24\u884c\u76ee)\u3002<\/p>\n<pre class=\"lang:js start-line:16 mark:6,9 decode:true \" >\r\nconst Foo = (props) =>\r\n  <div>\r\n    <button onClick={() => props.history.goBack()}>\r\n      Foo: back OK\r\n    <\/button><br \/>\r\n    <Bar \/><br \/>\r\n    <Baz history={props.history} \/><br \/>\r\n    <Qux \/><br \/>\r\n    <Quux \/><br \/>\r\n  <\/div>;\r\n<\/pre>\n<p>\u305f\u3060\u3057\u3001<a href=\"https:\/\/reactjs.org\/docs\/context.html#why-not-to-use-context\">\u524d\u8ff0<\/a>\u306e\u3088\u3046\u306b<\/p>\n<blockquote><p>\nIf you want your application to be stable, don\u2019t use context. It is an experimental API and it is likely to break in future releases of React.<\/p><\/blockquote>\n<p>\u5b9f\u9a13\u7684\u306a\u6a5f\u80fd\u3067\u3042\u308b\u305f\u3081\u3001context\u3092\u76f4\u63a5\u4f7f\u7528\u3059\u308b\u3053\u3068\u306f\u63a8\u5968\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002<\/p>\n<h2>withRouter()\u306f\u3069\u306e\u3088\u3046\u306b\u50cd\u304f\u306e\u304b<\/h2>\n<p>withRouter()\u306f\u76f4\u63a5context\u3092\u4f7f\u308f\u306a\u304f\u3066\u3082history\u3092\u53d7\u3051\u53d6\u308b\u3053\u3068\u304c\u3067\u304d\u308b\u6a5f\u80fd\u3067\u3059\u3002\u3053\u3061\u3089\u3082<a href=\"https:\/\/github.com\/ReactTraining\/react-router\/blob\/v4.2.2\/packages\/react-router\/modules\/withRouter.js#L9-L26\">\u5b9f\u88c5<\/a>\u3092\u898b\u3066\u307f\u307e\u3059\u3002<\/p>\n<pre class=\"lang:js start-line:9 mark:2,5-7,17decode:true \" >\r\nconst withRouter = (Component) => {\r\n  const C = (props) => {\r\n    const { wrappedComponentRef, ...remainingProps } = props\r\n    return (\r\n      <Route render={routeComponentProps => (\r\n        <Component {...remainingProps} {...routeComponentProps} ref={wrappedComponentRef}\/>\r\n      )}\/>\r\n    )\r\n  }\r\n\r\n  C.displayName = `withRouter(${Component.displayName || Component.name})`\r\n  C.WrappedComponent = Component\r\n  C.propTypes = {\r\n    wrappedComponentRef: PropTypes.func\r\n  }\r\n\r\n  return hoistStatics(C, Component)\r\n}\r\n<\/pre>\n<p>25\u884c\u76ee\u3067\u5b9f\u884c\u3057\u3066\u3044\u308bhoistStatics()\u3067\u3001Component\u306b\u5b9a\u7fa9\u3055\u308c\u3066\u3044\u308b\u9759\u7684\u95a2\u6570\u3092C\u306b\u8907\u88fd\u3057\u3066\u3001C\u3092\u8fd4\u3057\u3066\u3044\u307e\u3059\u3002(hoistStatics()\u306e\u5b9f\u88c5\u306f<a href=\"https:\/\/github.com\/mridgway\/hoist-non-react-statics\/blob\/master\/index.js#L35-L65\">\u3053\u3061\u3089<\/a>\u3002\u89e3\u8aac\u306f<a href=\"https:\/\/reactjs.org\/docs\/higher-order-components.html#static-methods-must-be-copied-over\">\u3053\u3061\u3089<\/a>\u3002)<br \/>\n10\u884c\u76ee\u4ee5\u964d\u3067C\u3092\u5b9a\u7fa9\u3057\u3066\u3044\u307e\u3059\u300213\u301c15\u884c\u76ee\u3092\u7c21\u5358\u306b\u66f8\u304f\u3068\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u306a\u308a\u3001&lt;Route&gt;\u306e\u914d\u4e0b\u306bComponent\u3092\u7f6e\u304f\u3053\u3068\u3067history\u3092\u4f7f\u3048\u308b\u3088\u3046\u306b\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n<pre class=\"lang:js decode:true \" >\r\n<Route render={() => <Component\/>}\/>\r\n<\/pre>\n<h2>\u307e\u3068\u3081<\/h2>\n<p>React Router\u306ehistory\u306e\u751f\u6210\u3068\u53d7\u3051\u6e21\u3057\u65b9\u6cd5\u306b\u3064\u3044\u3066\u3001\u5b9f\u88c5\u3092\u898b\u306a\u304c\u3089\u63a2\u308a\u307e\u3057\u305f\u3002<\/p>\n<ul>\n<li>history\u306f&lt;BrowserRouter&gt;\u3067\u751f\u6210\u3055\u308c\u3066\u3044\u308b\u3002<\/li>\n<li>history\u306e\u53d7\u3051\u6e21\u3057\u306fcontext\u3092\u7d4c\u7531\u3057\u3066\u884c\u308f\u308c\u308b\u3002(&lt;Router&gt;\u21d2&lt;Route&gt;)<\/li>\n<li>context API\u306f\u76f4\u63a5\u4f7f\u7528\u3057\u3066\u306f\u3044\u3051\u306a\u3044\u3002<\/li>\n<li>withRouter()\u3067\u306f&lt;Route&gt;\u306e\u914d\u4e0b\u306b\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u304c\u914d\u7f6e\u3055\u308c\u308b\u306e\u3067\u3001history\u304c\u4f7f\u7528\u3067\u304d\u308b\u3088\u3046\u306b\u306a\u308b\u3002<span style=\"color: gray;\">&lt;Route&gt;\u306e\u914d\u4e0b\u306b\u7f6e\u304b\u308c\u308b\u306a\u3089withRoute()\u3058\u3083\u306a\u3044\u306e\u304b\uff1f<\/span><\/li>\n<li>\u6848\u5916\u3001<span style=\"color: red;\">React\u306e\u516c\u5f0f\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u306b\u3057\u3063\u304b\u308a\u66f8\u3044\u3066\u3042\u308b<\/span>\u3002<\/li>\n<\/ul>\n<p>Enjoy your <span style=\"\ncolor: #61dafb;\nfont-size: 120%;\nfont-weight: 700;\nfont-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;\n-webkit-font-smoothing: antialiased;\nletter-spacing: 0.01em;\n\">React<\/span> life!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u3053\u308c\u306f TECHSCORE Advent Calendar 2017 \u306e1\u65e5\u76ee\u306e\u8a18\u4e8b\u3067\u3059\u3002<\/p>\n<p>SPA(SinglePageApplication)\u3092\u4f5c\u6210\u3059\u308b\u969b\u306b\u306f\u907f\u3051\u3066\u306f\u901a\u308c\u306a\u3044\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u3002<br \/><a href=\"https:\/\/www.techscore.com\/blog\/2017\/12\/01\/where_does_react-router-history_come_from\/\">\u7d9a\u304d\u3092\u8aad\u3080...<\/a><\/p>\n","protected":false},"author":44,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[276,18],"tags":[141,275,277],"_links":{"self":[{"href":"https:\/\/www.techscore.com\/blog\/wp-json\/wp\/v2\/posts\/14582"}],"collection":[{"href":"https:\/\/www.techscore.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.techscore.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.techscore.com\/blog\/wp-json\/wp\/v2\/users\/44"}],"replies":[{"embeddable":true,"href":"https:\/\/www.techscore.com\/blog\/wp-json\/wp\/v2\/comments?post=14582"}],"version-history":[{"count":154,"href":"https:\/\/www.techscore.com\/blog\/wp-json\/wp\/v2\/posts\/14582\/revisions"}],"predecessor-version":[{"id":15092,"href":"https:\/\/www.techscore.com\/blog\/wp-json\/wp\/v2\/posts\/14582\/revisions\/15092"}],"wp:attachment":[{"href":"https:\/\/www.techscore.com\/blog\/wp-json\/wp\/v2\/media?parent=14582"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.techscore.com\/blog\/wp-json\/wp\/v2\/categories?post=14582"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.techscore.com\/blog\/wp-json\/wp\/v2\/tags?post=14582"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}