问题描述
以下是引起我麻烦的文件:
Here is the file that's causing me trouble:
var Routers = React.createClass({
getInitialState: function(){
return{
userName: "",
relatives: []
}
},
userLoggedIn: function(userName, relatives){
this.setState({
userName: userName,
relatives: relatives,
})
},
render: function() {
return (
<Router history={browserHistory}>
<Route path="/" userLoggedIn={this.userLoggedIn} component={LogIn}/>
<Route path="feed" relatives={this.state.relatives} userName={this.state.userName} component={Feed}/>
</Router>
);
}
});
我正在尝试通过新的 this.state.relatives
和 this.state.userName
通过路由进入我的提要组件。但是我收到此错误消息:
I am trying to pass the new this.state.relatives
and this.state.userName
through the routes into my "feed"-component. But I'm getting this error message:
我知道为什么会这样,但是不知道我应该怎么过我的 Feed组件的状态。在过去的5个小时中,我一直在尝试解决此问题,而且我已经变得非常绝望!
I know why this happens, but don't know how else i'm supposed to pass the states to my "feed"-component. I've been trying to fix this problem for the past 5 hours and í'm getting quite desperate!
请帮助!
谢谢
Please help!Thanks
答案下面的内容很有帮助,我要感谢athors,但这并不是最简单的方法。
在我的情况下,最好的方法是这样:
更改路线时,您只需将一条消息附加如下:
The answers below were helpful and i thank the athors, but they were not the easiest way to do this.The best way to do it in my case turned out to be this:When you change routes you just attach a message to it like this:
browserHistory.push({pathname: '/pathname', state: {message: "hello, im a passed message!"}});
或者如果您通过链接进行操作:
or if you do it through a link:
<Link
to={{
pathname: '/pathname',
state: { message: 'hello, im a passed message!' }
}}/>
来源:
在您要访问的组件中,您可以像下面这样访问变量:
In the component you are trying to reach you can then access the variable like this for example:
componentDidMount: function() {
var recievedMessage = this.props.location.state.message
},
我希望这会有所帮助! :)
I hope this helps! :)
推荐答案
tl; dr 最好的选择是使用<$ c $这样的商店c> redux 或 mobx
在管理需要在整个应用程序中访问的状态时。这些库允许您的组件连接/观察状态,并随时了解任何状态更改。
tl;dr your best bet is to use a store like redux
or mobx
when managing state that needs to be accessible throughout your application. Those libraries allow your components to connect to/observe the state and be kept up to date of any state changes.
无法通过< Route>
组件传递道具的原因从某种意义上说,它们不是真正的组件,因为它们不会渲染任何东西。而是使用它们来构建路由配置对象。
The reason that you cannot pass props through <Route>
components is that they are not real components in the sense that they do not render anything. Instead, they are used to build a route configuration object.
这意味着:
<Router history={browserHistory}>
<Route path='/' component={App}>
<Route path='foo' component={Foo} />
</Route>
</Router>
等效于:
<Router history={browserHistory} routes={{
path: '/',
component: App,
childRoutes: [
{
path: 'foo',
component: Foo
}
]
}} />
仅在初始坐骑时评估路线,这就是为什么您不能将新道具传递给他们的原因。
The routes are only evaluated on the initial mount, which is why you cannot pass new props to them.
如果您有一些静态道具要传递给商店,则可以创建您自己的高阶组件会将其注入商店。不幸的是,这仅适用于静态道具,因为如上所述,< Route>
s仅被评估一次。
If you have some static props that you want to pass to your store, you can create your own higher order component that will inject them into the store. Unfortunately, this only works for static props because, as stated above, the <Route>
s are only evaluated once.
function withProps(Component, props) {
return function(matchProps) {
return <Component {...props} {...matchProps} />
}
}
class MyApp extends React.Component {
render() {
return (
<Router history={browserHistory}>
<Route path='/' component={App}>
<Route path='foo' component={withProps(Foo, { test: 'ing' })} />
</Route>
</Router>
)
}
}
使用 location.state
location.state
是导航时在组件之间传递状态的便捷方法。但是,它有一个主要缺点,那就是该状态仅在您的应用程序中导航时才存在。如果用户点击了指向您网站的链接,则该位置将没有任何状态。
Using location.state
location.state
is a convenient way to pass state between components when you are navigating. It has one major downside, however, which is that the state only exists when navigating within your application. If a user follows a link to your website, there will be no state attached to the location.
那么如何将数据传递到路线的组件
?一种常见的方式是使用 redux
或 mobx
之类的商店。使用 redux
,您可以使用更高阶的组件将
连接到商店。然后,当您的路线的组件
(实际上是将您的路线组件作为其子组件的HOC)呈现时,它可以从商店中获取最新信息。
So how do you pass data to your route's component
s? A common way is to use a store like redux
or mobx
. With redux
, you can connect
your component to the store using a higher order component. Then, when your route's component
(which is really the HOC with your route component as its child) renders, it can grab up to date information from the store.
const Foo = (props) => (
<div>{props.username}</div>
)
function mapStateToProps(state) {
return {
value: state.username
};
}
export default connect(mapStateToProps)(Foo)
我对 mobx
并不特别熟悉,但是据我所知,它甚至更容易设置。使用 redux
, mobx
或其他状态管理之一是在整个应用程序中传递状态的好方法。 / p>
I am not particularly familiar with mobx
, but from my understanding it can be even easier to setup. Using redux
, mobx
, or one of the other state management is a great way to pass state throughout your application.
没有商店
如果您不想使用商店怎么办?你不走运吗?不,但是您必须使用React的实验功能:。为了使用上下文
,您的父组件之一必须显式定义 getChildContext
方法以及 childContextTypes
对象。任何想要通过 context
访问这些值的子组件都需要定义一个 contextTypes
对象(类似于 propTypes
)。
Without A Store
What if you don't want to use a store? Are you out of luck? No, but you have to use an experimental feature of React: the context
. In order to use the context
, one of your parent components has to explicitly define a getChildContext
method as well as a childContextTypes
object. Any child component that wants to access these values through the context
would then need to define a contextTypes
object (similar to propTypes
).
class MyApp extends React.Component {
getChildContext() {
return {
username: this.state.username
}
}
}
MyApp.childContextTypes = {
username: React.PropTypes.object
}
const Foo = (props, context) => (
<div>{context.username}</div>
)
Foo.contextTypes = {
username: React.PropTypes.object
}
您甚至可以编写自己的高阶组件来自动注入 context
值作为< Route>
组件
的道具。这将是一个穷人商店。您可以使用它,但与使用上述存储库之一相比,它效率可能更高,并且存在更多的错误。
You could even write your own higher order component that automatically injects the context
values as props of your <Route>
component
s. This would be something of a "poor man's store". You could get it to work, but most likely less efficiently and with more bugs than using one of the aforementioned store libraries.
还有另一种为< Route>
提供道具的方法的组件
,但一次只能工作一个级别。本质上,当React Router基于当前路线渲染组件时,它首先为嵌套最深的匹配< Route>
创建一个元素。然后,在为下一个最深层嵌套的< Route>
创建元素时,它将该元素作为 children
传递。这意味着在第二个组件的 render
方法中,可以使用 React.cloneElement
克隆现有的 children
元素并向其中添加其他道具。
There is another way to provide props to a <Route>
's component
, but it only works one level at a time. Essentially, when React Router is rendering components based on the current route, it creates an element for the most deeply nested matched <Route>
first. It then passes that element as the children
prop when creating an element for the next most deeply nested <Route>
. That means that in the render
method of the second component, you can use React.cloneElement
to clone the existing children
element and add additional props to it.
const Bar = (props) => (
<div>These are my props: {JSON.stringify(props)}</div>
)
const Foo = (props) => (
<div>
This is my child: {
props.children && React.cloneElement(props.children, { username: props.username })
}
</div>
)
这当然很乏味,尤其是如果您需要通过< Route>
组件
的多个级别传递此信息。您还需要在基本的< Route>
组件中管理状态(即< Route path ='/'component = {Base} >
),因为您将无法从< Router>
的父组件注入状态。
This is of course tedious, especially if you were to need to pass this information through multiple levels of <Route>
component
s. You would also need to manage your state within your base <Route>
component (i.e. <Route path='/' component={Base}>
) because you wouldn't have a way to inject the state from parent components of the <Router>
.
这篇关于我如何通过React_router传递状态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!