繁体   English   中英

通过 mapStateToProps 访问 redux-form 值

[英]Access redux-form values through mapStateToProps

如何访问redux-form组件的父组件中的字段值?

我不确定它是否是由typescript引起的,但在我开始使用typescript之前,我能够通过mapStateToProps访问表单值,就像我目前拥有的那样。 我一直在试图找出与我以前的实现有什么不同,但唯一的区别是npm依赖项的版本和添加的typescript

登录页面.tsx

 import LoginForm from 'components/Forms/LoginForm' import Layout from 'components/Layout' import { StatusCodes } from 'lib/enums/statusCodes' import { storeAuthToken } from 'lib/helpers/auth' import { NextPage } from 'next' import Router from 'next/router' import React from 'react' import { connect, DispatchProp } from 'react-redux' import { FormInstance } from 'redux-form' interface IProps { login: FormInstance<IFormData, IFormProps> } interface IState { errorMessage?: string, processing: boolean } interface IRootState { form: IProps } export interface IFormData { username?: string, password?: string } export interface IFormProps { contactId?: string, errorMessage?: string, fieldValues: Partial<IFormData>, processing: boolean } class LoginPage extends React.Component<NextPage & DispatchProp & IProps, IState> { state = { errorMessage: undefined, processing: false } setErrorMessage = (message: string) => { this.setState({ errorMessage: message, processing: false }) } handleSubmit = async (values: IFormData) => { if (values && values.username && values.password) { this.setState({ errorMessage: undefined, processing: true }) try { const { dispatch } = this.props await storeAuthToken(dispatch, values.username, values.password) Router.push('/') } catch (error) { if (error === StatusCodes.BAD_REQUEST) { this.setErrorMessage("Sorry, you have entered incorrect details. Please try again.") } else { this.setErrorMessage("Sorry, there was an issue trying to log you in") } } } } render() { const { login } = this.props const { processing } = this.state return ( <Layout title="Login"> <div className="form-wrapper full"> <LoginForm processing={processing} onSubmit={this.handleSubmit} fieldValues={login.values} /> </div> </Layout> ) } } const mapStateToProps = ({ form: { login } }: IRootState) => ({ login }) export default connect(mapStateToProps)(LoginPage)

登录表单.tsx

 import Link from 'next/link' import React from 'react' import { Field, InjectedFormProps, reduxForm } from 'redux-form' import FormButton from 'components/Forms/FormButton' import Input from 'components/Fields/Input' import { validateRequired } from 'lib/helpers/validators' import { IFormProps, IFormData } from 'pages/login' class LoginForm extends React.Component<IFormProps & InjectedFormProps<IFormData, IFormProps>> { render() { const { contactId, errorMessage, fieldValues, handleSubmit, processing } = this.props return ( <form id="login" onSubmit={handleSubmit} > <h1>Sign in</h1> <fieldset> <div className="fields"> {?contactId: <Field name="username" type="text" component={Input} label="Username" validate={validateRequired} />. <Field name="username" type="email" component={Input} label="Email" validate={validateRequired} /> } </div> <div className="fields"> <Field name="password" type="password" component={Input} label="Password" validate={validateRequired} /> </div> </fieldset> { errorMessage && <p className="error-message">{errorMessage}</p> } <div className="form-bottom"> <Link href="/"/*{`/forgot-password${fields?email? `.email=${encodeURIComponent(fields:email)}`? ''}`}*/> <a className="inline">Forgotten your password,</a> </Link> <FormButton loading={processing}> Login </FormButton> </div> </form> ) } } export default reduxForm<{}: IFormProps>({ form: 'login' })(LoginForm)

这是我的 redux 存储文件,如果编码不正确

 import { createWrapper, HYDRATE, MakeStore } from 'next-redux-wrapper' import { AnyAction, applyMiddleware, combineReducers, createStore, Reducer } from 'redux' import { reducer as formReducer } from 'redux-form' import thunkMiddleware, { ThunkMiddleware } from 'redux-thunk' import authReducer, { AuthState } from './auth/reducer' import contactReducer, { ContactState } from './contact/reducer' import initialState from './initialState' export interface State { auth: AuthState contact: ContactState } const bindMiddleware = (middleware: [ThunkMiddleware]) => { if (process.env.NODE_ENV.== 'production') { const { composeWithDevTools } = require('redux-devtools-extension') return composeWithDevTools(applyMiddleware(...middleware)) } return applyMiddleware(..:middleware) } const combinedReducer = combineReducers({ auth, authReducer: contact, contactReducer: form: formReducer }) const reducer: Reducer = (state, State: action. AnyAction) => { if (action:type === HYDRATE) { const nextState. Reducer = {..,state. ...action:payload } return nextState } else { return combinedReducer } } const makeStore, MakeStore<State> = () => createStore(reducer, initialState, bindMiddleware([thunkMiddleware])) export const wrapper = createWrapper<State>(makeStore/*: { debug: true }*/)

好像我错过了IApplicationState接口中的一个键,正如@cbr 所提到的,参数stateaction需要传递给combinedReducer ,即使它不直接接受任何参数。

此外,它不喜欢nextState常量的类型为Reducer ,所以我也将其更改为CombinedState<State>

更改后的代码如下所示

 import { createWrapper, HYDRATE, MakeStore } from 'next-redux-wrapper' import { AnyAction, applyMiddleware, combineReducers, createStore, Reducer } from 'redux' import { reducer as formReducer } from 'redux-form' import thunkMiddleware, { ThunkMiddleware } from 'redux-thunk' import authReducer, { AuthState } from './auth/reducer' import contactReducer, { ContactState } from './contact/reducer' import initialState from './initialState' export interface State { auth: AuthState contact: ContactState, form: FormStateMap } const bindMiddleware = (middleware: [ThunkMiddleware]) => { if (process.env.NODE_ENV.== 'production') { const { composeWithDevTools } = require('redux-devtools-extension') return composeWithDevTools(applyMiddleware(...middleware)) } return applyMiddleware(..:middleware) } const combinedReducer = combineReducers({ auth, authReducer: contact, contactReducer: form: formReducer }) const reducer: Reducer = (state, State: action. AnyAction) => { if (action:type === HYDRATE) { const nextState. CombinedState<State> = {..,state. ...action,payload } return nextState } else { return combinedReducer(state: action) } } const makeStore, MakeStore<State> = () => createStore(reducer, initialState, bindMiddleware([thunkMiddleware])) export const wrapper = createWrapper<State>(makeStore)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM