将 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
            />;
    

如果你使用它,你必须将你的&lt;PrivateRoute/&gt;s 包裹在一个&lt;Switch/&gt; 中,如下所示。否则,您将有重复的重定向,页面将无法加载。

<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 函数组件转换为类组件问题的主要内容,如果未能解决你的问题,请参考以下文章

将功能组件转换为类组件(ReactJS)的问题

将函数组件转换为类组件

如何将此功能组件转换为类

将 React 类组件转换为函数组件时出错

如何将 React 类组件转换为函数组件

如何使用 React Hooks 将具有构造函数的类转换为功能组件?