【问题标题】:I am having teething problems with React + Redux for private page / public page authentication support对于私有页面/公共页面身份验证支持,我在使用 React + Redux 时遇到了初期问题
【发布时间】:2026-01-12 07:25:01
【问题描述】:

我已经阅读 React 有一段时间了,我了解了一些概念,我对 SAP UI5 和 Knockoutjs 也相当熟悉。我在VS2019中新建了一个React + Redux模板,这个例子有天气预报和反例。

在我真正开始我的应用程序之前,我想理清身份验证方面的问题——只需要一个假登录。我在柜台存储中的示例之后添加了一个身份验证会话存储,使用身份验证,我添加了登录和注销控制器,所有这些都可以工作。

到目前为止,我的登录组件如下所示:

import * as React from "react";
import { connect } from "react-redux";
import { RouteComponentProps } from 'react-router';
import { ApplicationState } from '../store';
import * as AuthSession from '../store/AuthSession';

type AuthProps =
    AuthSession.AuthState &
    typeof AuthSession.actionCreators &
    RouteComponentProps<{}>;


class Login extends React.PureComponent<AuthProps> {
    public render() {
        return (
            <React.Fragment>
                <h1>Login</h1>

                <p aria-live="polite">Current IsAuthenticated= <strong>{String(this.props.IsAuthenticated)}</strong></p>
                <p aria-live="polite">Current uuid= <strong>{this.props.uuid}</strong></p>

                <button type="button"
                    className="btn btn-primary btn-lg"
                    onClick={() => { this.props.auth(); }}>
                    Auth
                </button>

            </React.Fragment>
        );
    }
};

export default connect(
    (state: ApplicationState) => state.auth,
    AuthSession.actionCreators
)(Login);

我也一直在关注有关创建 LoggedInRoute 和 LoggedOutRoute 组件以引入和输出站点的各个方面的博客。该博客使用箭头函数而不是类,但是我无法理解这一点,所以我开始了自己的旅程。除了我的组件标签的属性(道具)之外,我真的在从 redux 商店传递我的状态时遇到问题。到目前为止,我的努力是这样的:

import * as React from "react";
import { connect } from "react-redux";
import { Route } from "react-router-dom";
import { RouteComponentProps } from 'react-router';
import { ApplicationState } from '../store';
import * as AuthSession from '../store/AuthSession';

type ParamProps = {
    exact?: boolean;
    path: string;
    component: React.ComponentType<any>;
    otherProps: any
};

type ComponentProps =
    AuthSession.AuthState &
    typeof AuthSession.actionCreators &
    RouteComponentProps<{}> &
    ParamProps;


class LoggedInRoute extends React.PureComponent<ComponentProps> {
    public render() {
        if (this.props.IsAuthenticated === true) {
            return (
                <React.Fragment>
                    <p aria-live="polite">Current IsAuthenticated= <strong>{String(this.props.IsAuthenticated)}</strong></p>
                    <p aria-live="polite">Current uuid= <strong>{this.props.uuid}</strong></p>

                    <Route
                        render={otherProps => (
                            <>
                                <React.Component {...otherProps} />
                            </>
                        )}
                    />
                </React.Fragment>
            );
        } else {
            return null;
        }
    }
};

export default connect(
    (state: ApplicationState, ownProps: ParamProps) => {
        return { ...state.auth, ...ownProps }
    },
    AuthSession.actionCreators,
)(LoggedInRoute);

这给了我一个错误:

/src/App.tsx(21,10) 中的 TypeScript 错误:Type '{ path: string; 组件:ConnectedComponentClass>; }' 不见了 'Readonly & ParamProps>' 类型的以下属性:位置、历史、匹配、uuid 和 还有2个。 TS2740 19 | 20 | > 21 | | ^ 22 | 23 | );

我可以在各种文档中清楚地看到,connect 旨在通过将自己的属性和 redux 状态注入子控件道具来做我想做的事,但显然这对我不起作用。

如何指定连接,以便我可以传递 redux 状态,并且还可以通过特定的命名属性以及其余属性来实现技巧? - 即 {stateprops, component, ...otherProps}

一个很长的问题,但我相信这对大多数 React 程序员来说很简单。

谢谢

【问题讨论】:

  • 我认为你应该使用 withRouter 见reacttraining.com/react-router/core/api/withRouter
  • 我想出的登录页面是基于我找到的一个示例。在该示例中,您可以看到 connect 仅将 state.auth 传递给 props,将 AuthSession.actionCreators 传递给 Dispatchers。登录组件不需要传入它的 Tags 属性。RouteComponentProps 值被注入而没有错误。我的组件使用了一个非常相似的模型,但我不知道如何传递我见过的所有相同的道具以及标签属性。我不认为我直接使用 RouteComponentProps,所以我认为我不需要替代品 - 我可以删除它吗?
  • 真的,问题是,我是否可以使用 return { ...state.auth, ...ownProps } 语法组合道具,如果可以,为什么我会突然收到 TS 类型错误?
  • 好的,抱歉我不擅长 Typescript ,如果传入了道具,那么它似乎是一些 Typescript 的东西。是不是你必须在接口中声明那些见*.com/questions/55501099/…

标签: reactjs redux react-redux tsx


【解决方案1】:

我看了这个多一点,并得到它的工作:

import * as React from "react";
import { connect } from "react-redux";
import { Route } from "react-router-dom";
import { RouteComponentProps } from 'react-router';
import { ApplicationState } from '../store';
import * as AuthSession from '../store/AuthSession';

type ParamProps = {
    exact?: boolean;
    path: string;
    component: React.ComponentType<any>;
    otherProps?: any
};

type ComponentProps =
    AuthSession.AuthState &
    typeof AuthSession.actionCreators &
    RouteComponentProps<{}> &
    ParamProps;


class LoggedInRoute extends React.PureComponent<ComponentProps> {
    public render() {
        var props = this.props;
        var Component = props.component;
        if (this.props.IsAuthenticated === true) {
            return (
                <React.Fragment>
                    <Route path={props.path}
                        render={otherProps => (
                            <>
                                <Component component={props.component} {...otherProps} />
                            </>
                        )}
                    />
                </React.Fragment>
            );
        } else {
            return (false);
;
        }
    }
};

export default connect(
    (state: ApplicationState, ownProps: any) => {
        const { component, path, ...rest } = ownProps;
        let op = {} as ParamProps;
        op.component = component;
        op.path = path;
        op.otherProps = rest;
        let st = { ...state.auth, ...op } as ComponentProps;
        return st;
        },
    AuthSession.actionCreators,
)(LoggedInRoute);

需要进行两项更改:

1) 是的,您可以在连接状态映射中组合道具。您只需返回您在类型中指定的特定字段(如预期的那样)。然而,注入的“ownProps”属性并没有与您指定的类型一起出现,您必须构造正确的类型。

2) 当我解决这个问题时,似乎 React 不知道如何渲染传入的组件。事实证明,如果该变量以一个大写字母。所以我将我的“组件”属性分配给了一个“组件”变量。现在我真的很喜欢这个功能,因为我理解了它。

:)

【讨论】:

    最近更新 更多