我在使用 React + Redux 的私人页面 / public 页面身份验证支持方面遇到了初期问题
I am having teething problems with React + Redux for private page / public page authentication support
我已经阅读了一段时间的 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);
这给了我一个错误:
TypeScript error in /src/App.tsx(21,10): Type '{ path: string;
component: ConnectedComponentClass<typeof Logout, Pick<AuthProps,
"location" | "history" | "match" | "staticContext">>; }' is missing
the following properties from type 'Readonly & ParamProps>': location, history, match, uuid, and
2 more. TS2740
19 |
20 |
> 21 |
| ^
22 |
23 | );
我可以在各种文档中清楚地看到,connect 旨在通过将自己的属性和 redux 状态注入子控件道具来执行我想要的操作,但显然这对我不起作用。
我如何指定连接,以便我可以传递 redux 状态,并且还可以通过特定的命名属性以及其余属性来实现这一技巧? - 即 {stateprops, component, ...otherProps}
一个很长的问题,但我相信这对大多数 React 程序员来说很简单。
谢谢
我仔细看了看它,让它工作了:
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) 是的,您可以在连接状态映射中编写您的道具。您只需 return 您在类型中指定的特定字段(如预期的那样)。然而,注入的 "ownProps" 属性 不包含您指定的类型,您必须构建正确的类型。
2) 当我完成这个时,React 似乎不知道如何渲染传入的组件。事实证明 JSX/TSX 将渲染保存在变量中的组件,如果该变量以大写字母开头。所以我将 "component" 属性 分配给了 "Component" 变量。现在我明白了,我真的很喜欢这个功能。
:)
我已经阅读了一段时间的 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);
这给了我一个错误:
TypeScript error in /src/App.tsx(21,10): Type '{ path: string; component: ConnectedComponentClass<typeof Logout, Pick<AuthProps, "location" | "history" | "match" | "staticContext">>; }' is missing the following properties from type 'Readonly & ParamProps>': location, history, match, uuid, and 2 more. TS2740 19 | 20 | > 21 | | ^ 22 | 23 | );
我可以在各种文档中清楚地看到,connect 旨在通过将自己的属性和 redux 状态注入子控件道具来执行我想要的操作,但显然这对我不起作用。
我如何指定连接,以便我可以传递 redux 状态,并且还可以通过特定的命名属性以及其余属性来实现这一技巧? - 即 {stateprops, component, ...otherProps}
一个很长的问题,但我相信这对大多数 React 程序员来说很简单。
谢谢
我仔细看了看它,让它工作了:
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) 是的,您可以在连接状态映射中编写您的道具。您只需 return 您在类型中指定的特定字段(如预期的那样)。然而,注入的 "ownProps" 属性 不包含您指定的类型,您必须构建正确的类型。
2) 当我完成这个时,React 似乎不知道如何渲染传入的组件。事实证明 JSX/TSX 将渲染保存在变量中的组件,如果该变量以大写字母开头。所以我将 "component" 属性 分配给了 "Component" 变量。现在我明白了,我真的很喜欢这个功能。
:)