将 React 函数组件转换为类组件问题
Posted
技术标签:
【中文标题】将 React 函数组件转换为类组件问题【英文标题】:Converting React function component to class component issue 【发布时间】:2017-09-27 11:31:21 【问题描述】:我有以下 react 功能组件来帮助支持使用 react-router 进行身份验证所需的路由。
const PrivateRoute = ( component: Component, ...rest ) => (
<Route ...rest render=props => (
isAuthenticated() ? (
<Component ...props/>
) : (
<Redirect to=
pathname: '/login',
state: from: props.location
/>
)
)/>
)
我需要将它从一个函数组件转换为一个类组件,这样我才能利用 React.Component 的 componentDidMount 方法。不幸的是,我无法弄清楚如何迁移它。如果我按原样处理,我需要复制 Component 和 ...rest 参数,但我不知道该怎么做。我想我可以通过 this.props.component 获取 Component 参数,但我不确定如何拉...rest。我是 JSX 和 ES6 的新手,因此非常感谢任何帮助或指导。
【问题讨论】:
你能用这个功能组件展示代码吗? 【参考方案1】:函数组件是render
函数,因此:
class PrivateRoute extends React.Component
render()
const component: Component, ...rest = this.props;
return (
<Route ...rest render=props => (
isAuthenticated() ? (
<Component ...props/>
) : (
<Redirect to=
pathname: '/login',
state: from: props.location
/>
)
)/>
);
或者,写得更易读:
class PrivateRoute extends React.Component
render()
const component: Component, ...rest = this.props;
const renderRoute = props =>
if (isAuthenticated())
return (
<Component ...props />
);
const to =
pathname: '/login',
state: from: props.location
;
return (
<Redirect to=to />
);
return (
<Route ...rest render=renderRoute/>
);
【讨论】:
谢谢。这很有帮助。 我不明白的是const component: Component, ...rest = this.props;
。这是做什么的,就像一个反转的变量?
@Mr.熊:我是destructuring assignment【参考方案2】:
通过扩展 Route
组件实现了一个不错的干净重构:
class PrivateRoute extends Route
render()
return isAuthenticated()
? super.render()
: <Redirect to=
pathname: '/login',
state: from: props.location
/>;
如果你使用它,你必须将你的<PrivateRoute/>s
包裹在一个<Switch/>
中,如下所示。否则,您将有重复的重定向,页面将无法加载。
<Router>
<Navbar/>
<SideDrawer/>
<Switch>
<Route path="/tokens" component=Login/>
<PrivateRoute exact path="/" component=ExampleComponent/>
<PrivateRoute path="/users" component=Users/>
<PrivateRoute path="/software" component=Software/>
</Switch>
</Router>
【讨论】:
【参考方案3】:@Sulthans 的回答是正确的,直接回答了您的问题。但我想用不同的方式提出建议。
根据您的问题,您的要求类似于在功能组件中使用生命周期挂钩,即 componentDidMount
。
如果您使用最新的反应,我想建议继续使用功能组件并使用提供的useEffect
实现挂钩
useEffect(() =>
console.log('mount it!');
, []); // passing an empty array as second argument triggers the callback in useEffect only after the initial render thus replicating `componentDidMount` lifecycle behaviour
我推荐这个是因为以下原因
它减少了样板代码 它促进可重复性 React 团队现在提倡使用函数组件。推荐阅读gradual adoption strategy。【讨论】:
【参考方案4】:对于您的情况,useEffect 挂钩将是最佳选择。
你可以简单地给你的组件添加使用效果钩子
const PrivateRoute = ( component: Component, ...rest ) =>
useEffect(()=>
// your logic for componentDidMount here
, []);
return (
<Route ...rest render=props => (
isAuthenticated() ? (
<Component ...props/>
) : (
<Redirect to=
pathname: '/login',
state: from: props.location
/>
)
)/>
)
【讨论】:
以上是关于将 React 函数组件转换为类组件问题的主要内容,如果未能解决你的问题,请参考以下文章