首先,我是React的新手。就像一个星期的经验:)所以,为一些琐碎的问题道歉。
我正在尝试找出与安全性相关的事情。与auth0,redux等集成在一起。看起来都不错。
现在,我正在尝试建立一条私有路线并面临问题。
这里是PrivateRoute
const PurePrivateRoute = ({ component, path, isAuthenticated, ...rest }) => {
const render = (props: any) => (isAuthenticated ? <Component {...props} /> : null);
return <Route path={path} render={render} {...rest} />;
};
const mapStateToProps = createSelector(AuthSelectors.isAuthenticated, isAuthenticated => ({ isAuthenticated }));
export const PrivateRoute = connect(mapStateToProps)(PurePrivateRoute);
这就是我的用法:<PrivateRoute exact path="/private" component={Private}/>
Private
是简单函数的无效组成部分。
export const Private = () => {
return <div>Private</div>;
};
通过身份验证时,出现以下错误:
index.js:1406 Warning: Component(...): No `render` method found on the returned component instance: you may have forgotten to define `render`.
in Component (at PrivateRoute.tsx:9)
in Router.Consumer (created by Route)
in Route (at PrivateRoute.tsx:11)
in PurePrivateRoute (created by Connect(PurePrivateRoute))
in Connect(PurePrivateRoute) (at AppRoutes.tsx:13)
in AppRoutes (at App.tsx:29)
in App (at src/index.tsx:17)
console.<computed> @ index.js:1406
r @ backend.js:6
warningWithoutStack @ react-dom.development.js:534
checkClassInstance @ react-dom.development.js:14149
mountClassInstance @ react-dom.development.js:14392
updateClassComponent @ react-dom.development.js:18429
beginWork$1 @ react-dom.development.js:20173
beginWork$$1 @ react-dom.development.js:25744
performUnitOfWork @ react-dom.development.js:24682
workLoopSync @ react-dom.development.js:24658
performSyncWorkOnRoot @ react-dom.development.js:24247
(anonymous) @ react-dom.development.js:12285
unstable_runWithPriority @ scheduler.development.js:701
runWithPriority$2 @ react-dom.development.js:12231
flushSyncCallbackQueueImpl @ react-dom.development.js:12280
flushSyncCallbackQueue @ react-dom.development.js:12268
discreteUpdates$1 @ react-dom.development.js:24401
discreteUpdates @ react-dom.development.js:1439
dispatchDiscreteEvent @ react-dom.development.js:5914
index.js:1406 Warning: Component(...): No `render` method found on the returned component instance: you may have forgotten to define `render`.
in Component (at PrivateRoute.tsx:9)
in Router.Consumer (created by Route)
in Route (at PrivateRoute.tsx:11)
in PurePrivateRoute (created by Connect(PurePrivateRoute))
in Connect(PurePrivateRoute) (at AppRoutes.tsx:13)
in AppRoutes (at App.tsx:29)
in App (at src/index.tsx:17)
console.<computed> @ index.js:1406
r @ backend.js:6
warningWithoutStack @ react-dom.development.js:534
checkClassInstance @ react-dom.development.js:14149
mountClassInstance @ react-dom.development.js:14392
updateClassComponent @ react-dom.development.js:18429
beginWork$1 @ react-dom.development.js:20173
callCallback @ react-dom.development.js:337
invokeGuardedCallbackDev @ react-dom.development.js:386
invokeGuardedCallback @ react-dom.development.js:439
beginWork$$1 @ react-dom.development.js:25768
performUnitOfWork @ react-dom.development.js:24682
workLoopSync @ react-dom.development.js:24658
performSyncWorkOnRoot @ react-dom.development.js:24247
(anonymous) @ react-dom.development.js:12285
unstable_runWithPriority @ scheduler.development.js:701
runWithPriority$2 @ react-dom.development.js:12231
flushSyncCallbackQueueImpl @ react-dom.development.js:12280
flushSyncCallbackQueue @ react-dom.development.js:12268
discreteUpdates$1 @ react-dom.development.js:24401
discreteUpdates @ react-dom.development.js:1439
dispatchDiscreteEvent @ react-dom.development.js:5914
react-dom.development.js:18483 Uncaught TypeError: instance.render is not a function
at finishClassComponent (react-dom.development.js:18483)
at updateClassComponent (react-dom.development.js:18438)
at beginWork$1 (react-dom.development.js:20173)
at HTMLUnknownElement.callCallback (react-dom.development.js:337)
at Object.invokeGuardedCallbackDev (react-dom.development.js:386)
at invokeGuardedCallback (react-dom.development.js:439)
at beginWork$$1 (react-dom.development.js:25768)
at performUnitOfWork (react-dom.development.js:24682)
at workLoopSync (react-dom.development.js:24658)
at performSyncWorkOnRoot (react-dom.development.js:24247)
at react-dom.development.js:12285
at unstable_runWithPriority (scheduler.development.js:701)
at runWithPriority$2 (react-dom.development.js:12231)
at flushSyncCallbackQueueImpl (react-dom.development.js:12280)
at flushSyncCallbackQueue (react-dom.development.js:12268)
at discreteUpdates$1 (react-dom.development.js:24401)
at discreteUpdates (react-dom.development.js:1439)
at dispatchDiscreteEvent (react-dom.development.js:5914)
finishClassComponent @ react-dom.development.js:18483
updateClassComponent @ react-dom.development.js:18438
beginWork$1 @ react-dom.development.js:20173
callCallback @ react-dom.development.js:337
invokeGuardedCallbackDev @ react-dom.development.js:386
invokeGuardedCallback @ react-dom.development.js:439
beginWork$$1 @ react-dom.development.js:25768
performUnitOfWork @ react-dom.development.js:24682
workLoopSync @ react-dom.development.js:24658
performSyncWorkOnRoot @ react-dom.development.js:24247
(anonymous) @ react-dom.development.js:12285
unstable_runWithPriority @ scheduler.development.js:701
runWithPriority$2 @ react-dom.development.js:12231
flushSyncCallbackQueueImpl @ react-dom.development.js:12280
flushSyncCallbackQueue @ react-dom.development.js:12268
discreteUpdates$1 @ react-dom.development.js:24401
discreteUpdates @ react-dom.development.js:1439
dispatchDiscreteEvent @ react-dom.development.js:5914
index.js:1406 The above error occurred in the <Component> component:
in Component (at PrivateRoute.tsx:9)
in Route (at PrivateRoute.tsx:11)
in PurePrivateRoute (created by ConnectFunction)
in ConnectFunction (at AppRoutes.tsx:13)
in Switch (at AppRoutes.tsx:10)
in AppRoutes (at App.tsx:29)
in div (at App.tsx:8)
in App (at src/index.tsx:17)
in Router (created by BrowserRouter)
in BrowserRouter (at src/index.tsx:16)
in Provider (at src/index.tsx:15)
Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://****/react-error-boundaries to learn more about error boundaries.
console.<computed> @ index.js:1406
r @ backend.js:6
logCapturedError @ react-dom.development.js:21827
logError @ react-dom.development.js:21863
update.callback @ react-dom.development.js:23206
callCallback @ react-dom.development.js:13915
commitUpdateEffects @ react-dom.development.js:13955
commitUpdateQueue @ react-dom.development.js:13945
commitLifeCycles @ react-dom.development.js:22136
commitLayoutEffects @ react-dom.development.js:25331
callCallback @ react-dom.development.js:337
invokeGuardedCallbackDev @ react-dom.development.js:386
invokeGuardedCallback @ react-dom.development.js:439
commitRootImpl @ react-dom.development.js:25069
unstable_runWithPriority @ scheduler.development.js:701
runWithPriority$2 @ react-dom.development.js:12231
commitRoot @ react-dom.development.js:24909
finishSyncRender @ react-dom.development.js:24304
performSyncWorkOnRoot @ react-dom.development.js:24284
(anonymous) @ react-dom.development.js:12285
unstable_runWithPriority @ scheduler.development.js:701
runWithPriority$2 @ react-dom.development.js:12231
flushSyncCallbackQueueImpl @ react-dom.development.js:12280
flushSyncCallbackQueue @ react-dom.development.js:12268
discreteUpdates$1 @ react-dom.development.js:24401
discreteUpdates @ react-dom.development.js:1439
dispatchDiscreteEvent @ react-dom.development.js:5914
react-dom.development.js:18483 Uncaught TypeError: instance.render is not a function
at finishClassComponent (react-dom.development.js:18483)
at updateClassComponent (react-dom.development.js:18438)
at beginWork$1 (react-dom.development.js:20173)
at HTMLUnknownElement.callCallback (react-dom.development.js:337)
at Object.invokeGuardedCallbackDev (react-dom.development.js:386)
at invokeGuardedCallback (react-dom.development.js:439)
at beginWork$$1 (react-dom.development.js:25768)
at performUnitOfWork (react-dom.development.js:24682)
at workLoopSync (react-dom.development.js:24658)
at performSyncWorkOnRoot (react-dom.development.js:24247)
at react-dom.development.js:12285
at unstable_runWithPriority (scheduler.development.js:701)
at runWithPriority$2 (react-dom.development.js:12231)
at flushSyncCallbackQueueImpl (react-dom.development.js:12280)
at flushSyncCallbackQueue (react-dom.development.js:12268)
at discreteUpdates$1 (react-dom.development.js:24401)
at discreteUpdates (react-dom.development.js:1439)
at dispatchDiscreteEvent (react-dom.development.js:5914)
我觉得我缺少一些非常简单的东西。任何想法表示赞赏!
可能的解决方案
所以我设法使其起作用的唯一方法是:
const PurePrivateRoute = ({ component, isAuthenticated, ...rest }) =>
isAuthenticated === true ? <Route {...rest} component={component} /> : <Redirect to="/login" />;
const mapStateToProps = createSelector(AuthSelectors.isAuthenticated, isAuthenticated => ({ isAuthenticated }));
export const PrivateRoute = connect(mapStateToProps)(PurePrivateRoute);
甚至是正确的方法吗?
由于您是新手,因此在这里是我所有项目的路由器组件。
它在打字稿中,但您会明白的。
您只需要向数组添加一个新对象,并全部设置一个创建的新路由即可。
您可以将该对象导入到任何组件中,也可以在重定向中使用。
import * as React from 'react'
import { BrowserRouter as Router, Route, Redirect } from 'react-router-dom'
export interface Props {}
interface routesObjectProp {
[key: string]: {
path: string
exact: boolean
privateRoute: boolean
Component: React.LazyExoticComponent<React.FunctionComponent>
}
}
export const routesObject: routesObjectProp = {
Login: {
path: '/',
exact: true,
privateRoute: false,
Component: React.lazy(() => import('./Containers/Login/Login')),
},
Signup: {
path: '/signup',
exact: true,
privateRoute: false,
Component: React.lazy(() => import('./Containers/Signup/Signup')),
},
Home: {
path: '/home',
exact: true,
privateRoute: true,
Component: React.lazy(() => import('./Containers/Home/Home')),
},
}
const Routes: React.SFC<Props> = () => {
return (
<Router>
{Object.keys(routesObject).map((item: string) => {
const { privateRoute, Component, path, exact } = routesObject[item]
return (
<Route
key={path}
path={path}
exact={exact}
render={() =>
privateRoute ? (
localStorage.getItem('accessToken') ? (
<Component />
) : (
<Redirect to={routesObject.Login.path} />
)
) : (
<Component />
)
}
/>
)
})}
</Router>
)
}
export default Routes
我认为其输出位于底部或return语句。这就是我的外观(我对其进行了修改以匹配您的外观)。尝试一下并开始分解(然后用旧版本替换每个部分),看看是什么引起了您的问题。
import React from 'react';
import { Route, Redirect } from 'react-router-dom';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
const PurePrivateRoute = ({ component, path, isAuthenticated, ...rest }) => (
<Route
{...rest}
render={(props: any) => (isAuthenticated ? <Component {...props} /> : null)}
/>
);
const mapStateToProps = createSelector(AuthSelectors.isAuthenticated, isAuthenticated => ({ isAuthenticated }));
export default connect(mapStateToProps)(PurePrivateRoute);