使用React、Redux与Redux-Form结合Firebase Auth实现密码重置时遭遇sendPasswordResetEmail参数错误的问题求助
解决sendPasswordResetEmail提示"email必须是有效字符串"的问题
Hey,我看了你的代码和报错信息,马上就找到问题所在啦——redux-form的handleSubmit会把表单里的所有字段打包成一个对象传给提交函数,而不是直接传单个的email值。你现在的onSubmit函数直接接收email参数,但实际上这个参数是个类似{ email: '用户输入的邮箱地址' }的对象,把对象传给Firebase的sendPasswordResetEmail,它自然会报错说"不是有效字符串"啦。
具体修复步骤
1. 修正提交函数的参数处理
把onSubmit的参数改成解构出email字段,或者先从对象里取出email:
onSubmit = async (formValues) => { // 从表单值对象里解构出email const { email } = formValues; try { await auth.sendPasswordResetEmail(email); alert("Password reset link sent!"); } catch (err) { console.error(err); // 用redux-form的SubmissionError来触发表单级错误提示,比alert更贴合表单逻辑 throw new SubmissionError({ _error: err.message }); } };
2. 加上表单验证(可选但强烈推荐)
你已经引入了FORGET_PASSWORD_SUBMIT_RULES,但redux-form的配置里没用上,加上验证可以提前拦截无效邮箱,避免到Firebase层面才报错:
const forgetPasswordReduxForm = reduxForm({ form: "forgetPasswordForm", validate: validate(FORGET_PASSWORD_SUBMIT_RULES) // 添加上验证规则 })(ForgetPassword);
3. 优化错误显示逻辑
现在你用的errorLogin是登录相关的错误状态,和密码重置不搭。改用redux-form自带的error prop来显示提交错误会更合适:
首先在组件的propTypes里添加error:
ForgetPassword.propTypes = { handleSubmit: PropTypes.func, error: PropTypes.string, // 新增redux-form的error prop loading: PropTypes.bool, };
然后在render里替换原来的错误提示:
{error && ( <Alert message={error} type="error" className="mb-3" /> )}
同时,mapStateToProps里的errorLogin可以删掉,密码重置的错误交给redux-form处理就好:
const mapStateToProps = (state) => { return { // 这里注意:当前用的LOGIN_REQUEST是登录的loading状态,建议改成密码重置专属的,比如FORGET_PASSWORD_REQUEST,避免状态混淆 loading: state.request[LOGIN_REQUEST], }; };
修正后的核心代码片段
class ForgetPassword extends Component { onSubmit = async (formValues) => { const { email } = formValues; try { await auth.sendPasswordResetEmail(email); alert("Password reset link sent!"); } catch (err) { console.error(err); throw new SubmissionError({ _error: err.message }); } }; render() { const { handleSubmit, error, loading } = this.props; return ( <WrapperContainer> <Row type="flex" align="middle" justify="center" style={{ height: "93vh" }} > <Col xxl={2} xl={3} md={4} sm={8} xs={10}> <div className="p-3 rounded box-shadow"> <Form onSubmit={handleSubmit(this.onSubmit)}> <LoginHeader /> {error && ( <Alert message={error} type="error" className="mb-3" /> )} <Input name="email" placeholder="Email" prefix={<UserOutlined />} autoFocus /> <Button loading={loading} type="submit" block> Submit </Button> <Divider /> <Link to="../login">Log In</Link> </Form> </div> </Col> </Row> <Footer /> </WrapperContainer> ); } } ForgetPassword.propTypes = { handleSubmit: PropTypes.func, error: PropTypes.string, loading: PropTypes.bool, }; const mapStateToProps = (state) => { return { // 建议替换为密码重置专属的LOADING状态常量 loading: state.request[LOGIN_REQUEST], }; }; const forgetPasswordReduxForm = reduxForm({ form: "forgetPasswordForm", validate: validate(FORGET_PASSWORD_SUBMIT_RULES) })(ForgetPassword); export default connect(mapStateToProps)(forgetPasswordReduxForm);
额外小建议
- 尽量别用
alert提示用户,换成Ant Design的message组件,用户体验会更好哦。 - 目前loading状态用的是登录的
LOGIN_REQUEST,最好在constants里新增一个FORGET_PASSWORD_REQUEST,然后在密码重置的action里dispatch这个状态,这样状态管理会更清晰,不会和登录的loading混在一起。
内容的提问来源于stack exchange,提问作者Leangsuo
相关产品推荐
相关产品推荐

