Reactルーターを使用するReact.jsアプリケーションには次の構造があります。
var Dashboard = require('./Dashboard');
var Comments = require('./Comments');
var Index = React.createClass({
render: function () {
return (
<div>
<header>Some header</header>
<RouteHandler />
</div>
);
}
});
var routes = (
<Route path="/" handler={Index}>
<Route path="comments" handler={Comments}/>
<DefaultRoute handler={Dashboard}/>
</Route>
);
ReactRouter.run(routes, function (Handler) {
React.render(<Handler/>, document.body);
});
いくつかのプロパティをComments
コンポーネントに渡したいです。
(通常、私はこれを次のようにします<Comments myprop="value" />
)
Reactルーターでこれを行う最も簡単で正しい方法は何ですか?
新しいリリース以降Route
、ラッパーを使用せずに、コンポーネントを介して小道具を直接渡すことができます。たとえば、propを使用しrender
ます。
成分:
class Greeting extends React.Component {
render() {
const {text, match: {params}} = this.props;
const {name} = params;
return (
<React.Fragment>
<h1>Greeting page</h1>
<p>
{text} {name}
</p>
</React.Fragment>
);
}
}
使用法:
<Route path="/greeting/:name" render={(props) => <Greeting text="Hello, " {...props} />} />
私の好みの方法は、Comments
コンポーネントをラップし、ラッパーをルートハンドラーとして渡すことです。
これは、変更が適用された例です。
var Dashboard = require('./Dashboard');
var Comments = require('./Comments');
var CommentsWrapper = React.createClass({
render: function () {
return (
<Comments myprop="myvalue"/>
);
}
});
var Index = React.createClass({
render: function () {
return (
<div>
<header>Some header</header>
<RouteHandler/>
</div>
);
}
});
var routes = (
<Route path="/" handler={Index}>
<Route path="comments" handler={CommentsWrapper}/>
<DefaultRoute handler={Dashboard}/>
</Route>
);
ReactRouter.run(routes, function (Handler) {
React.render(<Handler/>, document.body);
});
ラッパーを作成したくない場合は、次のように実行できると思います。
class Index extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<h1>
Index - {this.props.route.foo}
</h1>
);
}
}
var routes = (
<Route path="/" foo="bar" component={Index}/>
);
受け入れられた応答のcianticによるコメントからのコピー:
<Route path="comments" component={() => (<Comments myProp="value" />)}/>
これは私の意見では最も優雅な解決策です。できます。助けて頂きました。
これはRajeshのソリューションでありreact-router-小道具をハンドラーコンポーネントに渡します不便なreact-router-小道具をハンドラーコンポーネントに渡しますなく、React Router4用に更新されています。
コードは次のようになります。
<Route path="comments" render={(props) => <Comments myProp="value" {...props}/>}/>
のrender
代わりに使用することに注意してくださいcomponent
。その理由は、望ましくない再マウントを回避するためです。また、props
そのメソッドにを渡し、Commentsコンポーネントでオブジェクトスプレッド演算子(ES7プロポーザル)を使用して同じ小道具を使用します。
ColChの答えのフォローアップです。コンポーネントのラッピングを抽象化するのは非常に簡単です。
var React = require('react');
var wrapComponent = function(Component, props) {
return React.createClass({
render: function() {
return React.createElement(Component, props);
}
});
};
<Route path="comments" handler={wrapComponent(Comments, {myprop: value})}/>
このソリューションはまだテストしていないので、フィードバックは重要です。
この方法では、ルーターを介して送信された小道具(paramsなど)が上書き/削除されることに注意することが重要です。
小道具は、<RouteHandler>
(v0.13.xの場合)またはv1.0のルートコンポーネント自体に渡すことで渡すことができます。
// v0.13.x
<RouteHandler/>
<RouteHandler someExtraProp={something}/>
// v1.0
{this.props.children}
{React.cloneElement(this.props.children, {someExtraProp: something })}
(https://github.com/rackt/react-router/releases/tag/v1.0.0のアップグレードガイドから)
すべての子ハンドラーは同じ小道具のセットを受け取ります-これは状況に応じて役立つ場合とそうでない場合があります。
ES6を使用すると、コンポーネントラッパーをインラインにすることができます。
<Route path="/" component={() => <App myProp={someValue}/>} >
子供を渡す必要がある場合:
<Route path="/" component={(props) => <App myProp={someValue}>{props.children}</App>} >
以前の方法と非常に似ていますが、これを行うための新しい方法があります。
import { Match, Link, Miss } from 'react-router';
import Homepage from './containers/Homepage';
const route = {
exactly: true,
pattern: '/',
title: `${siteTitle} - homepage`,
component: Homepage
}
<Match { ...route } render={(props) => <route.component {...props} />} />
PSこれはアルファ版でのみ機能し、v4アルファ版のリリース後に削除されました。最新のv4では、パスと正確な小道具が含まれています。
react-legoサンプルアプリには、react-router-4ブランチのroutes.jsでこれを正確に実行するコードが含まれています
これが私が思いついた最もクリーンなソリューションです(React Router v4):
<Route
path="/"
component={props => <MyComponent {...props} foo="lol" />}
/>
MyComponent
まだと、、props.match
とprops.location
がありますprops.foo === "lol"
。
ステートレス関数コンポーネントでラップします。
<Router>
<Route
path='/'
component={({children}) =>
<MyComponent myProp={'myVal'}>{children}</MyComponent/>
}/>
</Router>
また、RouteHandlerミックスインを使用して、ラッパーコンポーネントを回避し、親の状態を小道具としてより簡単に渡すこともできます。
var Dashboard = require('./Dashboard');
var Comments = require('./Comments');
var RouteHandler = require('react-router/modules/mixins/RouteHandler');
var Index = React.createClass({
mixins: [RouteHandler],
render: function () {
var handler = this.getRouteHandler({ myProp: 'value'});
return (
<div>
<header>Some header</header>
{handler}
</div>
);
}
});
var routes = (
<Route path="/" handler={Index}>
<Route path="comments" handler={Comments}/>
<DefaultRoute handler={Dashboard}/>
</Route>
);
ReactRouter.run(routes, function (Handler) {
React.render(<Handler/>, document.body);
});
あなたは<RouterHandler/>
このように小道具を渡すことができます:
var Dashboard = require('./Dashboard');
var Comments = require('./Comments');
var Index = React.createClass({
render: function () {
var props = this.props; // or possibly this.state
return (
<div>
<header>Some header</header>
<RouteHandler {...props} />
</div>
);
}
});
これの欠点は、小道具を無差別に渡すことです。そのComments
ため、ルート構成によっては、実際には別のコンポーネントを対象とした小道具を受け取ることになります。props
は不変であるため大したことではありませんが、2つの異なるコンポーネントが、名前foo
は異なるが値が異なる小道具を期待している場合、これは問題になる可能性があります。
1.0および2.0では、createElement
prop ofRouter
を使用して、ターゲット要素を正確に作成する方法を指定できます。ドキュメントソース
function createWithDefaultProps(Component, props) {
return <Component {...props} myprop="value" />;
}
// and then
<Router createElement={createWithDefaultProps}>
...
</Router>
React Router v4ソリューション
今日、この質問に出くわしました。これが私が使用するパターンです。うまくいけば、これはより最新の解決策を探している人に役立つでしょう。
これが最善の解決策かどうかはわかりませんが、これが私の現在のパターンです。私は通常、よく使用するコンポーネントを関連する構成(ローダー、モーダルなど)とともに保持するコアディレクトリを持っており、次のようなファイルを含めます。
import React from 'react'
import { Route } from 'react-router-dom'
const getLocationAwareComponent = (component) => (props) => (
<Route render={(routeProps) => React.createElement(component,
{...routeProps, ...props})}/>
)
export default getLocationAwareComponent
次に、問題のファイルで、次のことを行います。
import React from 'react'
import someComponent from 'components/SomeComponent'
import { getLocationAwareComponent } from 'components/Core/getLocationAwareComponent'
const SomeComponent = getLocationAwareComponent(someComponent)
// in render method:
<SomeComponent someProp={value} />
コンポーネントのデフォルトのエクスポートを控えめなキャメルケースとしてインポートしていることに気付くでしょう。これにより、CamelCaseで新しい場所認識コンポーネントに名前を付けて、通常どおりに使用できるようになります。追加のインポートラインと割り当てラインを除いて、コンポーネントは期待どおりに動作し、すべてのルートプロップを追加して、すべてのプロップを正常に受け取ります。したがって、this.props.history.push()を使用して、コンポーネントのライフサイクルメソッドから問題なくリダイレクトしたり、場所を確認したりできます。
お役に立てれば!
es6関数とステートレス関数を組み合わせて、よりクリーンな結果を得ることができます。
import Dashboard from './Dashboard';
import Comments from './Comments';
let dashboardWrapper = () => <Dashboard {...props} />,
commentsWrapper = () => <Comments {...props} />,
index = () => <div>
<header>Some header</header>
<RouteHandler />
{this.props.children}
</div>;
routes = {
component: index,
path: '/',
childRoutes: [
{
path: 'comments',
component: dashboardWrapper
}, {
path: 'dashboard',
component: commentsWrapper
}
]
}
反応ルーター2.xの場合。
const WrappedComponent = (Container, propsToPass, { children }) => <Container {...propsToPass}>{children}</Container>;
そしてあなたのルートで...
<Route path="/" component={WrappedComponent.bind(null, LayoutContainer, { someProp })}>
</Route>
3番目のパラメーターが次のようなオブジェクトであることを確認してください{ checked: false }
。
Reactルーターの問題は、コンポーネントをレンダリングするため、小道具の受け渡しが停止することです。ナビゲーションルータは、他の一方で、あなたがあなた自身のコンポーネントをレンダリングすることができます。つまり、次のコードとそれに付随するJsFiddleが示すように、小道具を渡すためにフープを飛び越える必要はありません。
var Comments = ({myProp}) => <div>{myProp}</div>;
var stateNavigator = new Navigation.StateNavigator([
{key:'comments', route:''}
]);
stateNavigator.states.comments.navigated = function(data) {
ReactDOM.render(
<Comments myProp="value" />,
document.getElementById('content')
);
}
stateNavigator.start();
Rajesh Narothの回答に基づいて、ルーターの有無にかかわらずコンポーネントを使用します。
class Index extends React.Component {
constructor(props) {
super(props);
}
render() {
const foo = (this.props.route) ? this.props.route.foo : this.props.foo;
return (
<h1>
Index - {foo}
</h1>
);
}
}
var routes = (
<Route path="/" foo="bar" component={Index}/>
);
または、次のようにすることもできます。
export const Index = ({foo, route}) => {
const content = (foo) ? foo : (route) ? route.foo : 'No content found!';
return <h1>{content}</h1>
};
以下のようなソリューションを使用すると、これはv3.2.5で機能します。
<Route
path="/foo"
component={() => (
<Content
lang="foo"
meta={{
description: lang_foo.description
}}
/>
)}
/>
または
<Route path="/foo">
<Content
lang="foo"
meta={{
description: lang_foo.description
}}
/>
</Route>
私はすでにルーターパスの小道具を反応させてコンポーネントをルーティングするこれに答えルーターパスの小道具を反応させてコンポーネントをルーティングする。
小道具をルートコンポーネントに渡す方法はいくつかあります。
react-router v5を使用すると、コンポーネントでラップしてルートを作成できるため、このように目的のコンポーネントに小道具を簡単に渡すことができます。
<Route path="/">
<Home name="Sai" />
</Route>
同様に、v5では子の小道具を使用できます。
<Route path="/" children={ <Home name="Sai" />} />
react-router v4を使用している場合は、レンダープロップを使用して渡すことができます。
<Route path="/" render={() => <Home name="Sai" />} />
(元々はhttps://reactgo.com/react-router-pass-props/に投稿されていました)
react-router 2.5.2の場合、解決策はとても簡単です。
//someConponent
...
render:function(){
return (
<h1>This is the parent component who pass the prop to this.props.children</h1>
{this.props.children && React.cloneElement(this.props.children,{myProp:'value'})}
)
}
...
カスタムルートコンポーネントを使用すると、これはReact Routerv3で可能です。
var Dashboard = require('./Dashboard');
var Comments = require('./Comments');
var routes = (
<Route path="/" handler={Index}>
<MyRoute myprop="value" path="comments" handler={Comments}/>
<DefaultRoute handler={Dashboard}/>
</Route>
);
<MyRoute>
コンポーネントコードについては、次のようになります。
import React from 'react';
import { Route } from 'react-router';
import { createRoutesFromReactChildren } from 'react-router/lib//RouteUtils';
const MyRoute = () => <div><MyRoute> elements are for configuration only and should not be rendered</div>;
MyRoute.createRouteFromReactElement = (element, parentRoute) => {
const { path, myprop } = element.props;
// dynamically add crud route
const myRoute = createRoutesFromReactChildren(
<Route path={path} />,
parentRoute
)[0];
// higher-order component to pass myprop as resource to components
myRoute.component = ({ children }) => (
<div>
{React.Children.map(children, child => React.cloneElement(child, { myprop }))}
</div>
);
return myRoute;
};
export default MyRoute;
カスタムルートコンポーネントアプローチの詳細については、この件に関する私のブログ投稿を確認してください:http://marmelab.com/blog/2016/09/20/custom-react-router-component.html
これはおそらく、Cookieハンドラーでreact-router-domを使用するための最良の方法です。
index.jsで
import React, { Component } from 'react'
import {Switch,Route,Redirect} from "react-router-dom"
import {RouteWithLayout} from "./cookieCheck"
import Login from "../app/pages/login"
import DummyLayout from "../app/layouts/dummy"
import DummyPage from "../app/pages/dummy"
export default ({props})=>{
return(
<Switch>
<Route path="/login" component={Login} />
<RouteWithLayout path="/dummy" layout={DummyLayout} component={DummyPage}
{...props}/>
<Redirect from="/*" to="/login" />
</Switch>
)
}
cookieCheckを使用します
import React , {createElement} from 'react'
import {Route,Redirect} from "react-router-dom"
import {COOKIE,getCookie} from "../services/"
export const RouteWithLayout = ({layout,component,...rest})=>{
if(getCookie(COOKIE)==null)return <Redirect to="/login"/>
return (
<Route {...rest} render={(props) =>
createElement(layout, {...props, ...rest}, createElement(component,
{...props, ...rest}))
}
/>
)
}
class App extends Component {
constructor(props){
super(props);
this.state = {
data:null
}
}
componentDidMount(){
database.ref().on('value', (snapshot) =>{
this.setState({
data : snapshot.val()
})
});
}
render(){
// const { data } = this.state
return (
<BrowserRouter>
<Switch>
<Route exact path = "/" component = { LandingPage } />
<Route
path='/signup'
render = { () => <Signup data = {this.state.data} />} />
</Switch>
</BrowserRouter>
);
}
};
export default App;
Reba McEntire が息子の Shelby Blackstock と共有しているクリスマスの伝統について学びましょう。
メーガン・マークルとマライア・キャリーが自然な髪の上でどのように結合したかについて、メーガンの「アーキタイプ」ポッドキャストのエピソードで学びましょう.
ハリー王子が家族、特にチャールズ王とウィリアム王子との関係について望んでいると主張したある情報源を発見してください。
ワイノナ・ジャッドが、母親のナオミ・ジャッドが亡くなってから初めての感謝祭のお祝いを主催しているときに、彼女が今では家長であることをどのように認識したかを学びましょう.
Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?
The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!
ランボルギーニの創設者であるフェルッチオランボルギーニが100歳になるのは毎日ではありません(そうです、彼は死んでいて、まだ死んでいると思います。
Appleが自動車分野に参入するという噂はかなり前から渦巻いており、AppleウォッチャーがSixtyEight Researchという会社がAppleの自動車研究開発のシェル会社である可能性が高いと判断したとき、その渦巻きは本当に渦巻いた。また、会社が購入した車は1台だけであることが知られており、その車はAppleが何を考えているかについての手がかりでいっぱいになる可能性があることも伝えています。
太陽系の外側にある架空の大きな物体である惑星Xの探索は、何十年にもわたって人間を魅了してきました。その検索の最新の章は、地球の10倍の大きさで、公転周期が15であるほど遠くにある惑星を指しています。
カムニュートンは昨日、簡単な265ヤードと3回のタッチダウンでファルコンズを引き裂き、別の素晴らしいゲームをしました。その日のハイライトは、上のタッチダウンスローでした。これは、視聴するたびにばかげているだけです。
ロシアのフィギュアスケーター、カミラ・バリエバが関与したドーピング事件が整理されているため、チームは2022年北京冬季オリンピックで獲得したメダルを待っています。
何千人ものAmazonの買い物客がMulberry Silk Pillowcaseを推奨しており、現在販売中. シルクの枕カバーにはいくつかの色があり、髪を柔らかく肌を透明に保ちます。Amazonで最大46%オフになっている間にシルクの枕カバーを購入してください
ラファイエット警察署は、「不審な男性が女性に近づいた」という複数の苦情を受けて、12 月にパデュー大学の教授の捜査を開始しました。
私たちの周りの世界と同じように、言語は常に変化しています。以前の時代では、言語の変化は数年または数十年にわたって発生していましたが、現在では数日または数時間で変化する可能性があります。
認知症を患っている 91 歳のアジア人女性が最近、47 番街のアウター サンセット地区でロメオ ロレンゾ パーハムに襲われました。伝えられるところによると、被害者はサンフランシスコの通りを歩いていたところ、容疑者に近づき、攻撃を受け、暴行を受けました。
“And a river went out of Eden to water the garden, and from thence it was parted and became into four heads” Genesis 2:10. ? The heart is located in the middle of the thoracic cavity, pointing eastward.
人々にチャンスを与えることは、人生で少し遅すぎると私は信じています。寛大に。