javascript - 将具有参数的无状态 React 组件转换为有状态
问题描述
在我的 React JS 项目中,我正在处理PrivateRoutes
. 我已经完成了这个私有路由和使用react-router-dom
.
https://reacttraining.com/react-router/web/example/auth-workflow
根据这个文档,他们创建了一个PrivateRoute
作为无状态组件。
但我的要求是将它转换为有状态的 React 组件,因为我想将我的PrivateRoute
组件连接到 redux 存储。
这是我的代码。
无状态组件
import React from 'react';
import {Route, Redirect} from 'react-router-dom';
import {auth} from './Authentication';
const PrivateRoute = ({ component: Component, ...rest }) => (
<Route
{...rest}
render={props =>
auth.isAuthenticated ? (
<Component {...props} />
) : (
<Component {...props} action="login"/>
)
}
/>
);
export default PrivateRoute;
我将此组件转换为React
像这样的有状态组件。
有状态的 React 组件
import React from 'react';
import {Route, Redirect} from 'react-router-dom';
import {auth} from './Authentication';
import {connect} from 'react-redux';
class PrivateRoute extends React.Component {
render({ component: Component, ...rest }) {
return (
<Route
{...rest}
render={props =>
this.props.customer.isAuthenticated ? (
<Component {...props} />
) : (
<Component {...props} action="login"/>
)
}
/>
);
}
}
export default connect(state => state)(PrivateRoute);
在这里,我正在从 redux 存储中读取数据以检查用户是否经过身份验证。
但是我将无状态组件转换为有状态的方式是不正确的。
我 render({ component: Component, ...rest })
是否正确传递了论点?
将PrivateRoute
与 redux 存储连接会产生任何问题,props
因为state=>state
将映射state
到props
以及...rest
将有props
对象?
不确定代码内部发生了什么。
更新 AppRouter.js
import React from 'react';
import {BrowserRouter, Route, Switch} from 'react-router-dom';
import {TransitionGroup, CSSTransition} from 'react-transition-group';
import PrivateRoute from './PrivateRoute';
import HomePage from './../components/HomePage';
import AboutUs from './../components/AboutUs';
import ContactUs from './../components/ContactUs';
import PageNotFound from './../components/PageNotFound';
import RestaurantList from '../components/RestaurantList';
import RestaurantMenu from '../components/RestaurantMenu';
import UserDetails from '../components/UserDetails';
import OrderConfirmation from '../components/OrderConfirmation';
import CustomerAccount from '../components/CustomerAccount';
import Logout from '../components/sections/Logout';
export default () => {
return (
<BrowserRouter>
<Route render={({location}) => (
<TransitionGroup>
<CSSTransition key={location.key} timeout={300} classNames="fade">
<Switch location={location}>
<Route path="/" component={HomePage} exact={true}/>
<Route path="/about" component={AboutUs} />
<Route path="/contact" component={ContactUs} />
<Route path="/restaurants" component={RestaurantList} />
<Route path="/select-menu" component={RestaurantMenu} />
<PrivateRoute path="/user-details" component={UserDetails} />
<PrivateRoute path="/order-confirmation" component={OrderConfirmation} />
<PrivateRoute path="/my-account" component={CustomerAccount} />
<PrivateRoute path="/logout" component={Logout} />
<Route component={PageNotFound} />
</Switch>
</CSSTransition>
</TransitionGroup>
)} />
</BrowserRouter>
);
}
解决方案
通常,将无状态功能组件 (SFC) 转换为 aComponent
是这样完成的:
为它创建
class
外壳。将 SFC 的主体复制到
render
方法中。如果 SFC 是箭头函数,则return
根据需要添加 a 到render
.props
将render
方法中的任何引用更改为this.props
(或仅const { props } = this;
在顶部添加)。SFC 在其参数中接收它们的道具,但组件将它们作为其构造函数的参数接收;默认构造函数会将它们保存为this.props
.在您的情况下,它在其参数上使用解构,因此您可以
this.props
在解构的右侧执行相同的操作:const { component: Component, ...rest } = this.props;
而已。在您的代码中,您已经向render
函数添加了参数,但它没有被任何参数调用,并且您只是随意更改为(包括props
出于某种原因更改为)。this.props
auth.isAuthenticated
this.props.customer.isAuthenticated
所以应用上面的1-3:
// #1 - the shell
class PrivateRoute extends React.Component {
// #2 - `render`, with the body of the SFC inside
render() {
// #3 - destructure `this.props`
const { component: Component, ...rest } = this.props;
// #2 (part 2) - add `return`
return <Route
{...rest}
render={props =>
auth.isAuthenticated ? (
<Component {...props} />
) : (
<Component {...props} action="login"/>
)
}
/>;
}
}
推荐阅读
- javascript - 阿贾克斯第一次尝试
- c++ - 标记联合中字符串影响的分段错误
- sql-server - 是 Null 导致访问表超过 2GB 并失败
- python - Pygame 绘制矩形
- c# - 使用 Span 没有任何分配的子字符串
- python - 从 python struct.pack (big-endian) 转换为整数列表
- python - 熊猫在循环中添加列值而不使用 iloc
- javascript - 使用带有 JavaScript 的网站来抓取 HTML 源代码
- java - 已知公钥时生成 Java RSA 私钥
- webpack - Webpack 3.10.0 无法缩小该行: return [`${new Date().toISOString()} Twilsock ${prefix}:`].concat(Array.from(args));