mapDispatchToProps 类型挑战(typescript react-redux)
mapDispatchToProps type challenge (typescript react-redux)
我无法确定我的 mapDispatchToProps 的类型。在下面检查 SignInComponent const mapDispatchToProps
。
看起来很简单,因为函数将 signIn() 作为参数,我可以从中获取类型。但是我无法弄清楚。
这是我的 autAction.ts:
import firebase from 'firebase/app'
import { Dispatch } from 'react';
type AuthAction = {
type: string,
err?: unknown
}
export const signIn = (credentials: {email:string, password:string}) => {
return (dispatch: Dispatch<AuthAction>) => {
firebase.auth().signInWithEmailAndPassword(
credentials.email,
credentials.password
).then(() => {
dispatch({ type: 'LOGIN_SUCCESS'})
}).catch((err) => {
dispatch({ type: 'LOGIN_ERROR', err})
});
}
}
这是我的登录组件:
import React, { BaseSyntheticEvent, Component } from 'react'
import { connect } from 'react-redux';
import { signIn } from '../../store/actions/authActions';
type IConnectedDispatch = {
signIn: typeof signIn
}
interface IMyComponentProps {
signIn: (credentials: {email:string, password:string}) => void;
}
class SignIn extends Component<IMyComponentProps> {
state = {
email:'',
password:''
}
handleChange = (e:BaseSyntheticEvent) => {
this.setState({
[e.target.id]: e.target.value
});
}
handleSubmit = (e:BaseSyntheticEvent) => {
e.preventDefault();
//console.log(this.state);
this.props.signIn(this.state);
}
render() {
return (
<div className="container">
<form onSubmit={this.handleSubmit} className="white">
<h5 className="grey-text text-darken-3">Sing In</h5>
<div className="input-field">
<label htmlFor="email">Email</label>
<input type="email" id="email" onChange={this.handleChange}/>
</div>
<div className="input-field">
<label htmlFor="password">Password</label>
<input type="password" id="password" onChange={this.handleChange}/>
</div>
<div className="input-field">
<button className="btn pink lighten-1 z-depth-0">Login</button>
</div>
</form>
</div>
)
}
}
type AuthAction = {
type:string,
err?: unknown
}
const mapDispatchToProps = (dispatch: any): IConnectedDispatch => { //TYPE CHALLENGE HERE.
return {
signIn: (credentials:{ email:string, password:string}) => dispatch(signIn(credentials))
}
}
export default connect<React.FunctionComponent>(null,mapDispatchToProps)(SignIn)
这样试试:
import React, { BaseSyntheticEvent, Component } from 'react'
import { connect } from 'react-redux';
import { signIn } from '../../store/actions/authActions';
interface IMyComponentProps {
signIn: typeof signIn
}
class SignIn extends Component<IMyComponentProps> {
state = {
email:'',
password:''
}
handleChange = (e:BaseSyntheticEvent) => {
this.setState({
[e.target.id]: e.target.value
});
}
handleSubmit = (e:BaseSyntheticEvent) => {
e.preventDefault();
//console.log(this.state);
this.props.signIn(this.state);
}
render() {
return (
<div className="container">
<form onSubmit={this.handleSubmit} className="white">
<h5 className="grey-text text-darken-3">Sing In</h5>
<div className="input-field">
<label htmlFor="email">Email</label>
<input type="email" id="email" onChange={this.handleChange}/>
</div>
<div className="input-field">
<label htmlFor="password">Password</label>
<input type="password" id="password" onChange={this.handleChange}/>
</div>
<div className="input-field">
<button className="btn pink lighten-1 z-depth-0">Login</button>
</div>
</form>
</div>
)
}
}
export default connect(null, { signIn } )(SignIn)
如@liamgbs 的回答所示,您的 mapDispatchToProps
并不是必需的,但我确实想回答您有关打字稿问题的问题。
mapDispatchToProps
是一个函数,它将 dispatch
作为参数,returns 是道具的键控对象。所以类型本质上是 (dispatch: Dispatch)
.
问题是 Dispatch
在这里使用的定义,因为多个包都有自己的类型。 react
和 redux
中 Dispatch
的更基本定义预计 dispatch
将仅使用普通操作对象调用。来自 signIn
动作创建者的 return 值是 dispatch
的函数(“thunk”)。所以你需要使用 redux-thunk
包中的类型。
{signIn: typeof signIn}
也不完全正确,因为您正在 调用 signIn
而不仅仅是 return 调用它。实际界面是您的 IMyComponentProps
,其中 signIn
是一个 void
函数。
import { ThunkDispatch } from "redux-thunk";
interface LoginCredentials {
email: string;
password: string;
}
interface IMyComponentProps {
signIn: (credentials: LoginCredentials) => void;
}
const mapDispatchToProps = ( dispatch: ThunkDispatch<any, never, AuthAction> ): IMyComponentProps => {
return {
signIn: (credentials: LoginCredentials) => dispatch(signIn(credentials))
};
};
烦人的是,ThunkDispatch
要求您设置所有三个泛型。第一个 any
代表您的 redux 状态的类型,因此您可以根据需要将其替换为实际类型。 never
是您未使用的 action creator 中的额外参数。
我无法确定我的 mapDispatchToProps 的类型。在下面检查 SignInComponent const mapDispatchToProps
。
看起来很简单,因为函数将 signIn() 作为参数,我可以从中获取类型。但是我无法弄清楚。
这是我的 autAction.ts:
import firebase from 'firebase/app'
import { Dispatch } from 'react';
type AuthAction = {
type: string,
err?: unknown
}
export const signIn = (credentials: {email:string, password:string}) => {
return (dispatch: Dispatch<AuthAction>) => {
firebase.auth().signInWithEmailAndPassword(
credentials.email,
credentials.password
).then(() => {
dispatch({ type: 'LOGIN_SUCCESS'})
}).catch((err) => {
dispatch({ type: 'LOGIN_ERROR', err})
});
}
}
这是我的登录组件:
import React, { BaseSyntheticEvent, Component } from 'react'
import { connect } from 'react-redux';
import { signIn } from '../../store/actions/authActions';
type IConnectedDispatch = {
signIn: typeof signIn
}
interface IMyComponentProps {
signIn: (credentials: {email:string, password:string}) => void;
}
class SignIn extends Component<IMyComponentProps> {
state = {
email:'',
password:''
}
handleChange = (e:BaseSyntheticEvent) => {
this.setState({
[e.target.id]: e.target.value
});
}
handleSubmit = (e:BaseSyntheticEvent) => {
e.preventDefault();
//console.log(this.state);
this.props.signIn(this.state);
}
render() {
return (
<div className="container">
<form onSubmit={this.handleSubmit} className="white">
<h5 className="grey-text text-darken-3">Sing In</h5>
<div className="input-field">
<label htmlFor="email">Email</label>
<input type="email" id="email" onChange={this.handleChange}/>
</div>
<div className="input-field">
<label htmlFor="password">Password</label>
<input type="password" id="password" onChange={this.handleChange}/>
</div>
<div className="input-field">
<button className="btn pink lighten-1 z-depth-0">Login</button>
</div>
</form>
</div>
)
}
}
type AuthAction = {
type:string,
err?: unknown
}
const mapDispatchToProps = (dispatch: any): IConnectedDispatch => { //TYPE CHALLENGE HERE.
return {
signIn: (credentials:{ email:string, password:string}) => dispatch(signIn(credentials))
}
}
export default connect<React.FunctionComponent>(null,mapDispatchToProps)(SignIn)
这样试试:
import React, { BaseSyntheticEvent, Component } from 'react'
import { connect } from 'react-redux';
import { signIn } from '../../store/actions/authActions';
interface IMyComponentProps {
signIn: typeof signIn
}
class SignIn extends Component<IMyComponentProps> {
state = {
email:'',
password:''
}
handleChange = (e:BaseSyntheticEvent) => {
this.setState({
[e.target.id]: e.target.value
});
}
handleSubmit = (e:BaseSyntheticEvent) => {
e.preventDefault();
//console.log(this.state);
this.props.signIn(this.state);
}
render() {
return (
<div className="container">
<form onSubmit={this.handleSubmit} className="white">
<h5 className="grey-text text-darken-3">Sing In</h5>
<div className="input-field">
<label htmlFor="email">Email</label>
<input type="email" id="email" onChange={this.handleChange}/>
</div>
<div className="input-field">
<label htmlFor="password">Password</label>
<input type="password" id="password" onChange={this.handleChange}/>
</div>
<div className="input-field">
<button className="btn pink lighten-1 z-depth-0">Login</button>
</div>
</form>
</div>
)
}
}
export default connect(null, { signIn } )(SignIn)
如@liamgbs 的回答所示,您的 mapDispatchToProps
并不是必需的,但我确实想回答您有关打字稿问题的问题。
mapDispatchToProps
是一个函数,它将 dispatch
作为参数,returns 是道具的键控对象。所以类型本质上是 (dispatch: Dispatch)
.
问题是 Dispatch
在这里使用的定义,因为多个包都有自己的类型。 react
和 redux
中 Dispatch
的更基本定义预计 dispatch
将仅使用普通操作对象调用。来自 signIn
动作创建者的 return 值是 dispatch
的函数(“thunk”)。所以你需要使用 redux-thunk
包中的类型。
{signIn: typeof signIn}
也不完全正确,因为您正在 调用 signIn
而不仅仅是 return 调用它。实际界面是您的 IMyComponentProps
,其中 signIn
是一个 void
函数。
import { ThunkDispatch } from "redux-thunk";
interface LoginCredentials {
email: string;
password: string;
}
interface IMyComponentProps {
signIn: (credentials: LoginCredentials) => void;
}
const mapDispatchToProps = ( dispatch: ThunkDispatch<any, never, AuthAction> ): IMyComponentProps => {
return {
signIn: (credentials: LoginCredentials) => dispatch(signIn(credentials))
};
};
烦人的是,ThunkDispatch
要求您设置所有三个泛型。第一个 any
代表您的 redux 状态的类型,因此您可以根据需要将其替换为实际类型。 never
是您未使用的 action creator 中的额外参数。