使用Redux action作为onSubmit时如何处理React Final Form的提交错误?
React Final Form 处理 Redux 异步提交错误的最佳方案
React Final Form 原生支持 onSubmit 返回 Promise,只要返回符合格式的错误对象,表单会自动关联对应字段的错误状态,无需类似 Redux Form stopSubmit 的手动触发操作,具体实现步骤如下:
1. 改造 Redux Thunk 异步 Action
目前主流版本的 redux-thunk(v2.3.0+)默认支持 Thunk 函数返回 Promise,你只需在登录异常的分支,把需要展示的表单错误一并返回即可:
import { FORM_ERROR } from 'final-form' export const login = ({ username, password }) => async dispatch => { const config = { headers: { 'Content-Type': 'application/json' } }; const body = JSON.stringify({ username, password }); try { const res = await axios.post('/api/auth/login', body, config); dispatch({ type: LOGIN_SUCCESS, payload: res.data }); } catch (err) { dispatch({ type: LOGIN_FAIL, payload: err.response?.data }); // 构造并返回表单错误对象 if (err.response?.status === 401) { // 字段级错误,key和表单字段名对应 return { password: '用户名或密码错误' } } // 全局提交错误,用FORM_ERROR作为固定key return { [FORM_ERROR]: '登录失败,请稍后重试' } } };
2. 改造表单 onSubmit 方法
将原来的同步提交方法改为异步,接收 Action 返回的错误对象直接返回给 React Final Form 即可:
onSubmit = async formValues => { const submitError = await this.props.login(formValues); // 直接返回错误对象,Final Form会自动处理状态 if (submitError) return submitError; };
3. 错误状态展示
字段级错误和全局错误的展示逻辑和 Redux Form 用法基本一致:
字段错误展示
<Field name="password"> {({ input, meta }) => ( <div> <input {...input} type="password" placeholder="密码" /> {meta.touched && meta.error && <span className="error">{meta.error}</span>} </div> )} </Field>
全局错误展示
<Form onSubmit={this.onSubmit}> {({ handleSubmit, meta }) => ( <form onSubmit={handleSubmit}> {meta.error && <div className="global-error">{meta.error}</div>} {/* 其余表单字段 */} <button type="submit">登录</button> </form> )} </Form>
内容的提问来源于stack exchange,提问作者honter safioun
相关产品推荐
相关产品推荐

