如何在redux-form中分发change action?代码报错排查
问题分析与解决
你遇到的TypeError: (0 , _reactRedux.dispatch) is not a function错误,主要是三个关键问题导致的:
错误点1:错误导入dispatch
你不能直接从react-redux中导入dispatch——dispatch并不是react-redux的导出成员,它是通过connect高阶组件注入到组件props中的,或者在函数组件中使用useDispatch钩子获取,而非直接导入。
错误点2:未正确使用redux-form的change方法
你已经通过connect和reduxForm的装饰,把change这个action creator注入到了组件的props中,但你在changeStuff里却试图手动调用dispatch(change(...)),这完全没必要——redux-form的change方法已经被绑定了当前form的上下文和dispatch,直接调用即可。
错误点3:冗余的reduxForm配置
你在reduxForm的配置对象里添加了change: reduxForm.change和dispatch:reduxForm.dispatch,这是多余的,redux-form会自动处理这些方法的注入,不需要手动配置。
修正后的完整代码
import React from 'react' import { connect } from 'react-redux' // 去掉错误的dispatch导入 import { Field, reduxForm, formValueSelector } from 'redux-form' let SelectingFormValuesForm = props => { // 直接从props解构出change方法 const { favoriteColorValue, fullName, handleSubmit, hasEmailValue, pristine, reset, submitting, change } = props // 修改changeStuff,直接使用change方法,无需手动调用dispatch const changeStuff = () => { // 这里不需要传form名,因为redux-form已经绑定了当前的form标识 change('firstName', 'Bertje') } return ( <form onSubmit={handleSubmit}> <div> <label>First Name</label> <div> <Field name="firstName" component="input" type="text" placeholder="First Name" /> </div> </div> <div> <label>Last Name</label> <div> <Field name="lastName" component="input" type="text" placeholder="Last Name" /> </div> </div> <div> <label htmlFor="hasEmail">Has Email?</label> <div> <Field name="hasEmail" id="hasEmail" component="input" type="checkbox" /> </div> </div> {hasEmailValue && ( <div> <label>Email</label> <div> <Field name="email" component="input" type="email" placeholder="Email" /> </div> </div> )} <div> <label>Favorite Color</label> <div> <Field name="favoriteColor" component="select"> <option /> <option value="#ff0000">Red</option> <option value="#00ff00">Green</option> <option value="#0000ff">Blue</option> </Field> </div> </div> {favoriteColorValue && ( <div style={{ height: 80, width: 200, margin: '10px auto', backgroundColor: favoriteColorValue }} /> )} <div> <button type="submit" disabled={pristine || submitting}> Submit {fullName} </button> <button type="button" disabled={pristine || submitting} onClick={reset}> Clear Values </button> <button type="button" onClick={changeStuff}> Change first name </button> </div> </form> ) } // 去掉冗余的change和dispatch配置,只保留form标识 SelectingFormValuesForm = reduxForm({ form: 'selectingFormValues' // 唯一的form标识 })(SelectingFormValuesForm) // 保持connect的逻辑不变 const selector = formValueSelector('selectingFormValues') SelectingFormValuesForm = connect(state => { const hasEmailValue = selector(state, 'hasEmail') const favoriteColorValue = selector(state, 'favoriteColor') const { firstName, lastName } = selector(state, 'firstName', 'lastName') return { hasEmailValue, favoriteColorValue, fullName: `${firstName || ''} ${lastName || ''}` } })(SelectingFormValuesForm) export default SelectingFormValuesForm
额外说明
redux-form的change方法已经自动绑定了当前form的名字,所以调用时只需要传入字段名和新值即可,不需要再传递form标识。- 如果你需要手动调用
dispatch(比如处理自定义action),可以通过connect的第二个参数(mapDispatchToProps)注入,或者在函数组件中使用useDispatch钩子,但在这个场景下完全不需要。
内容的提问来源于stack exchange,提问作者bier hier
相关产品推荐
相关产品推荐

