如何使用react路由器将顶级组件状态传递给Routes
How do you pass top level component state down to Routes using react-router?
我已经使用react-router
设置了一个React应用程序,该应用程序可以通过Firebase进行身份验证。
我已经完成了这项工作,但我现在希望能够从主App
组件管理登录用户(auth)的状态,并将其传递给子组件,而不必查询每个组件中的auth状态。
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, Link, browserHistory } from 'react-router';
import { createHistory } from 'history';
/*
Firebase
*/
import Auth from './modules/Auth';
import Helpers from './modules/Helpers';
// Auth.unauth();
/*
Import app modules
*/
import LogIn from './modules/LogIn';
import LogOut from './modules/LogOut';
import NotFound from './modules/NotFound';
import Register from './modules/Register';
import Dashboard from './modules/Dashboard';
import ResetPassword from './modules/ResetPassword';
import ChangePassword from './modules/ChangePassword';
import MyAccount from './modules/MyAccount';
const App = React.createClass({
getInitialState: function() {
return {
loggedIn: Auth.getAuth(),
userType: null
}
},
setUserLevel: function(authData) {
if(authData){
Auth.child('users/'+authData.uid+'/user_level').once('value',
(snapshot) => {
this.setState({ userType: Helpers.getUserType(snapshot.val()) })
},
(error) => {
this.setState({
userType: Helpers.getUserType(0),
error: error
});
}
);
}
},
updateAuth: function(loggedIn) {
// console.log('Updating Auth');
this.setUserLevel(loggedIn);
this.setState({
loggedIn: loggedIn
})
},
componentWillMount: function() {
Auth.onAuth(this.updateAuth);
},
render: function() {
var regButton = (this.state.loggedIn) ? null : (<Link className="Navigation__link" to="register">Register</Link>);
var accountButton = (this.state.loggedIn) ? (<Link className="Navigation__link" to="account">My Account</Link>) : null;
return (
<div>
<nav className="Navigation">
{this.state.loggedIn ? (
<Link className="Navigation__link" to="/logout">Log out</Link>
) : (
<Link className="Navigation__link" to="/login">Sign in</Link>
)}
{regButton}
{accountButton}
<Link className="Navigation__link" to="dashboard">Dashboard</Link>
</nav>
<div>
{this.props.children}
</div>
</div>);
}
})
function requireAuth(nextState, replaceState) {
if (!Auth.getAuth())
replaceState({ nextPathname: nextState.location.pathname }, '/login')
}
function notWhenLoggedIn(nextState, replaceState) {
if (Auth.getAuth())
replaceState({ nextPathname: nextState.location.pathname }, '/dashboard')
}
var routes = (
<Router history={createHistory()}>
<Route path="/" component={App}>
<Route path="/login" component={LogIn} onEnter={notWhenLoggedIn} />
<Route path="/logout" component={LogOut} onEnter={requireAuth} />
<Route path="/register" component={Register} onEnter={notWhenLoggedIn} />
<Route path="/resetpassword" component={ResetPassword} onEnter={notWhenLoggedIn} />
<Route path="/change-password" component={ChangePassword} onEnter={requireAuth} />
<Route path="/dashboard" component={Dashboard} onEnter={requireAuth} />
<Route path="/account" component={MyAccount} onEnter={requireAuth} />
<Route path="*" component={NotFound} />
</Route>
</Router>
)
ReactDOM.render(routes, document.querySelector('#main'));
我现在陷入了困境,因为我找不到将App
组件的loggedIn state
作为子组件的属性向下传递的方法。
这在react-router
中可能吗?
我所知道的最好的方法是使用React.Children实用程序。这里有一个快速的Codepen来查看这个概念的实际操作。http://codepen.io/anon/pen/RrKbjZ
因此,您的示例中App
组件的render()
函数中的代码看起来是这样的。
render: function() {
var regButton = (this.state.loggedIn) ? null : (<Link className="Navigation__link" to="register">Register</Link>);
var accountButton = (this.state.loggedIn) ? (<Link className="Navigation__link" to="account">My Account</Link>) : null;
var childrenWithProps = React.Children.map(this.props.children, (Child, i) => {
return React.cloneElement(Child, {
loggedIn: this.state.loggedIn
});
});
return (
<div>
<nav className="Navigation">
{
this.state.loggedIn ?
(<Link className="Navigation__link" to="/logout">Log out</Link>) :
(<Link className="Navigation__link" to="/login">Sign in</Link>)
}
{regButton}
{accountButton}
<Link className="Navigation__link" to="dashboard">Dashboard</Link>
</nav>
<div>
{childrenWithProps}
</div>
</div>
);
}
我以前也遇到过同样的问题。这个问题可能会对您有所帮助。
https://github.com/rackt/react-router/issues/1857
但是这种传递参数的方法是不推荐的,尤其是当你正在构建一个大型应用程序时。
我推荐一些js的状态管理器,比如"Redux"。
相关文章:
- 事件和状态
- 获取选择框的状态
- 相位器状态未捕获参考错误
- 如何更改reactjs中外部/独立组件的状态或属性
- 如何使用密码检测网络中的状态连接
- Ember.js-接口状态应该存储在哪里
- 混合 ui-sref 和 $state.go 在 Angular ui-router 中进行状态转换
- 在Angular 2中布线期间保持零部件处于活动状态
- 在mvc应用程序中,在回发时保留最初隐藏的文本框的隐藏或可见状态
- XMLHttpRequest未返回值-状态202
- 使用javascript反复检查用户在facebook上的登录状态
- 如何使bxslider仅在移动视图中处于活动状态
- 获取ASP.NET Ajax Timer状态
- React redux初始化功能,无论状态变化如何
- 无法在现有状态转换期间更新-未使用任何非法的setState()
- 悬停下拉菜单即使在鼠标移出后也保持活动状态
- 从组件状态的数组中删除元素
- iOS 中的按钮触摸状态
- 使用AngularJS中的UI路由器将状态重定向到默认子状态
- 如何使用react路由器将顶级组件状态传递给Routes