当前位置: 首页 > 知识库问答 >
问题:

将具有参数的无状态React组件转换为有状态

吴高洁
2023-03-14

在我的React JS项目中,我正在处理Private ateRoutes。我已经通过了使用react-router-dom进行私有路由和身份验证的示例。

https://reacttraining.com/react-router/web/example/auth-workflow

根据这个留档,他们创建了一个私人路由作为无状态组件。

但我的要求是将其转换为有状态的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商店连接是否会导致propsas状态出现问题=

不确定代码中发生了什么。

更新批准者。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>
    );
}

共有3个答案

孟思远
2023-03-14

我有两个问题。

1) 如何转换为有状态功能组件?2) 连接到redux商店后,道具是否会产生问题?

我的第一个问题是由T. J. Crowder提供的答案解决的。

对于第二个查询,我尝试将redux store连接到Private ateRoad,并且我确实得到了我正在寻找的数据。

这是为我工作的代码。

import React from 'react';
import {Route, Redirect} from 'react-router-dom';
import {connect} from 'react-redux';

class PrivateRoute extends React.Component {
  render() {
    const { component: Component, ...rest } = this.props;
    const {customer} = this.props;

    return <Route
      {...rest}
      render={props =>
        customer.isAuthenticated ? (
          <Component {...props} />
        ) : (
          <Component {...props} action="login"/>
        )
      }
    />;
  }
}

export default connect(state => state)(PrivateRoute);

使用这段代码,我得到了来自路由的数据,以及道具中的redux状态。

这是从routesconst{component:component,…rest}=This获取数据。道具

这是来自redux存储区的数据。

赵浩邈
2023-03-14

您的有状态组件应该是:

class PrivateRoute extends React.Component {
  render() {
    const { component: Component, ...rest } = this.props;
    return (
      <Route
        {...rest}
        render={props =>
          this.props.customer.isAuthenticated ? (
            <Component {...props} />
          ) : (
            <Component {...props} action="login"/>
          )
        }
      />
    );
  }
}

请注意,Routerender参数中存在一些问题。这里有props作为函数参数,但仍然使用this。道具。客户,不知道用例,因此请根据您的应用程序进行修复。

除了它组件和所有其他数据都已经存在于组件的道具中。它在组件中的render方法的参数中不可用。可以在render方法中编写与无状态组件中可用的相同的解构,如上面的代码所示。

连接PrivateRoute和redux商店是否会对道具造成任何问题?

是的,会的。您连接到存储的方式将使存储数据在组件的props中可用,但传递到组件的外部props将不可用。

为此,您必须在MapStateTops函数中处理它:

const mapStateToProps = (state, ownProps) => ({
    ...state,
    ...ownProps
});

这里mapstatetops有第二个参数,该参数具有传递给组件的外部自己的道具。因此,您还必须返回它,以使其在组件道具中可用。

现在连接就像:

export default connect(mapStateToProps)(PrivateRoute);

韩禄
2023-03-14

一般来说,将无状态函数组件(SFC)转换为Component是这样完成的:

>

将SFC的主体复制到render方法。如果SFC是一个箭头函数,则根据需要添加一个返回,以呈现

render方法中对props的任何引用更改为this。props(或者在顶部添加const{props}=this;)。SFC在其参数中接收道具,但组件将其作为构造函数的参数接收;默认构造函数将它们保存为this。道具

在你的例子中,它对它的参数使用了析构,所以你可以对析构的右边的this.props做同样的事情:

 const { component: Component, ...rest } = this.props;

就这样。在您的代码中,您已经向render函数添加了参数,但它不会被任何参数调用,您只将props更改为this。道具有点随意(包括出于某种原因将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"/>
        )
      }
    />;
  }
}
 类似资料:
  • 本文向大家介绍描述下在react中无状态组件和有状态组件的区别是什么?相关面试题,主要包含被问及描述下在react中无状态组件和有状态组件的区别是什么?时的应答技巧和注意事项,需要的朋友参考一下 1,无状态组件主要用来定义模板,接收来自父组件props传递过来的数据,使用{props.xxx}的表达式把props塞到模板里面。无状态组件应该保持模板的纯粹性,以便于组件复用。创建无状态组件如下: v

  • 我已经开始学习ReactJS,有一个关于无状态和有状态组件的问题。一般来说,我遵循组件和容器的分离,如下所示。有状态函数在组件文件夹中,其他逻辑操作在容器文件夹下。文件夹结构 让我们思考材料UI下拉列表。 为了打开和关闭下拉菜单和方法更改打开状态,这意味着它是有状态组件。但没有其他变化(省略年龄设置)。它似乎是可重用的组件,但包括状态与非常简单的操作,如打开和关闭。我应该放入哪个文件夹?容器还是组

  • 当我试图插入一个新的食谱元素时,我的项目总是崩溃。我使用在能够根据需要更新食谱(例如删除,编辑等)。 如果我将语句切换到,我可以插入元素而没有问题,但是由于删除,我无法删除触发状态更改,并需要状态更改来反映更新而不是道具。有人对这个问题有什么建议吗?谢谢! 配方列表: 配方容器: 配方表:

  • 我无法将状态从父组件转发到子组件,这两个组件是类组件。将状态从父组件转发到子组件时,我希望在子组件中使用状态showModal变量作为状态变量show as: 这个变量被用来激活模态。当我将其用作this.props.show时,状态已被转发到子组件并进行更新,但当我在子组件中this.state中使用道具时,状态尚未更新。有人知道问题出在哪里吗? 第一父组件: 第二子组件:

  • 我对口水还不熟悉。我试图理解Drools提供的无状态会话和有状态会话之间的区别。 根据我的初步理解, 在无状态会话的情况下,如果在任何规则的操作执行过程中修改了事实,则不会将其重新提交给推理引擎以找出与修改后的事实匹配的新规则。 在状态会话的情况下,如果在任何规则的操作执行过程中修改了事实,则它将被重新提交给推理引擎以找出与修改后的事实相匹配的新规则,然后执行相应的操作。 因此,当我试图通过编写一