根据我的eslint错误建议,我一直在努力将这个反应组件重写为纯函数。我的目标是让它与反应路由器一起工作,而不会发出警告/错误。
这是类组件:
class PrivateRouteContainer extends React.Component {
render() {
const {
isAuthenticated,
component: Component,
...props
} = this.props
return (
<Route
{...props}
render={props =>
isAuthenticated
? <Component {...props} />
: (
<Redirect to={{
pathname: '/login',
state: { from: props.location }
}} />
)
}
/>
)
}
}
这是我的尝试:
const PrivateRouteContainer = (props) => {
const {
isAuthenticated,
isLoggingIn,
} = props;
return (
<Route
{...props}
render={() =>
(isAuthenticated || isLoggingIn
? <Component {...props} />
: (
<Redirect to={{
pathname: '/login',
state: { from: props.location },
}}
/>
))
}
/>
);
};
这似乎不起作用,因为我收到错误: 警告:您不应该使用和使用相同的路线;将被忽略
如果有帮助,以下是我的路线定义:
import React from 'react';
import PropTypes from 'prop-types';
import { Route, Switch } from 'react-router';
import { connect } from 'react-redux';
import { Redirect } from 'react-router-dom';
import { ConnectedRouter } from 'react-router-redux';
import PrivateRoute from './PrivateRoute';
import Login from '../containers/LoginPage';
import Home from '../containers/HomePage';
import List from '../containers/ListPage';
import Edit from '../containers/EditPage';
import { logout } from '../redux/auth/oauth/actions';
const ConnectedSwitch = connect(state => ({ location: state.routerReducer.location }))(Switch);
const mapStateToProps = state => ({
isLoggingIn: state.authReducer.isLoggingIn,
isAuthenticated: state.authReducer.isAuthenticated,
error: state.authReducer.error,
});
const Logout = connect(mapStateToProps)(({ dispatch }) => {
dispatch(logout());
return <Redirect to="/" />;
});
const Routes = props =>
(
<ConnectedRouter history={props.history}>
<ConnectedSwitch>
<Route path="/" exact component={connect(mapStateToProps)(Home)} />
<PrivateRoute path="/list" exact component={List} />
<PrivateRoute path="/edit" component={Edit} />
<Route path="/login" exact component={connect(mapStateToProps)(Login)} />
<Route path="/logout" exact component={Logout} />
</ConnectedSwitch>
</ConnectedRouter>
);
Routes.propTypes = {
history: PropTypes.shape({}).isRequired,
};
export default connect(mapStateToProps)(Routes);
答案 0 :(得分:0)
这只是一个错字,因为我认为你理解&#34;这&#34;没有在无状态组件中定义:
const {
isAuthenticated,
isLoggingIn,
} = props; // <-- remove this. here
答案 1 :(得分:0)
const PrivateRouteContainer = (props) => (
<Route
{...props}
render={() =>
(props.isAuthenticated || props.isLoggingIn
? <Component {...props} />
: (
<Redirect to={{
pathname: '/login',
state: { from: props.location },
}}
/>
))
}
/>
)
答案 2 :(得分:0)
您是否考虑过创建一个utils文件,例如auth.js
,而不是将身份验证作为道具传递?如果用户经过验证,该文件很容易返回?
如果我们在组件处置中纠缠认证条件,我们将添加一个我们将不得不关心的附加层,这需要关心父组件的生命周期以及它如何评估认证。这也意味着你要转移到<Route />
组件,它不关心或不需要关心的一些道具,这也可能有问题
为了使事情更清楚,还可以尝试使用对象解构属性,而不是在组件内部声明const,以及rest操作符。仅传递路由需要的路由,以及<Component />
,仅传递组件需要的路径。这可能会导致错误,
最终结果是这样的:
import { isAuthenticated } from 'utils/auth';
const PrivateRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={props => (
isAuthenticated() ? (
<Component {...props} />
) : (
<Redirect to={{ pathname: '/login' }} />
)
)}/>
);
答案 3 :(得分:0)
我不确定这是否是最佳方法,但它似乎正在起作用......
import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { Route } from 'react-router';
import { Redirect } from 'react-router-dom';
const RedirectToLogin = () => (
<Redirect to={{ pathname: '/login' }} />
);
const PrivateRouteContainer = props => (
<Route
{...props}
component={props.isAuthenticated || props.isLoggingIn ?
props.component :
RedirectToLogin}
/>
);
PrivateRouteContainer.propTypes = {
isAuthenticated: PropTypes.bool.isRequired,
isLoggingIn: PropTypes.bool.isRequired,
component: PropTypes.func.isRequired,
};
const PrivateRoute = connect(state => ({
isAuthenticated: state.authReducer.isAuthenticated,
isLoggingIn: state.authReducer.isLoggingIn,
}))(PrivateRouteContainer);
export default PrivateRoute;