【问题标题】:React/Redux clear form elements values after submit提交后 React/Redux 清除表单元素值
【发布时间】:2017-02-15 08:33:23
【问题描述】:

通过 axios 库成功提交后,我在清除输入中的值和选择 react form 中的表单元素时遇到问题。只想提一下我不使用redux-form。

我不知道我是否走在正确的轨道上,到目前为止这是我的工作流程:我用react-bootstrap 编写了一个表单,通过道具提供每个输入和选择值,然后我通过这些访问和更新状态道具。我已经编写了用于更新输入值的动作和减速器,并且在我的组件中调度了一个动作,但是第二个动作和应该在提交后清除值的减速器没有按预期工作。这是主要问题,我不确定我是否在正确的位置分派了 FORM_RESET 操作表单,因为我在负责将数据发布到服务器的操作中调用它,并且在成功回调时我分派了 FORM_RESET。

以下是与此问题相关的代码。

/* actionRegister.js */

let _registerUserFailure = (payload) => {
    return {
        type: types.SAVE_USER_FAILURE,
        payload
    };
};
let _registerUserSuccess = (payload) => {
    return {
        type: types.SAVE_USER_SUCCESS,
        payload,
        is_Active: 0,
        isLoading:true
    };
};

let _hideNotification = (payload) => {
    return {
        type: types.HIDE_NOTIFICATION,
        payload: ''
    };
};

//asynchronous helpers
export function registerUser({ //use redux-thunk for asynchronous dispatch
    timezone,
    password,
    passwordConfirmation,
    email,
    name
}) {
    return dispatch => {
        axios.all([axios.post('/auth/signup', {
                    timezone,
                    password,
                    passwordConfirmation,
                    email,
                    name,
                    is_Active: 0
                })
                // axios.post('/send', {email})
            ])
            .then(axios.spread(res => {
                dispatch(_registerUserSuccess(res.data.message));
                dispatch(formReset()); //here I dispatch clearing form data
                setTimeout(() => {
                    dispatch(_hideNotification(res.data.message));
                }, 10000);
            }))
            .catch(res => {
                dispatch(_registerUserFailure(res.data.message)); //BE validation and passport error message
                setTimeout(() => {
                    dispatch(_hideNotification(res.data.message));
                }, 10000);
            });
    };
}

/* actionForm.js */

//synchronous action creators
export function formUpdate(name, value)  {
    return {
        type: types.FORM_UPDATE_VALUE,
        name, //shorthand from name:name introduced in ES2016
        value
    };
}
export function formReset() {
  return {
    type: types.FORM_RESET
  };
}

/* reducerRegister.js */

const INITIAL_STATE = {
  error:{},
  is_Active:false,
  isLoading:false
};
const reducerSignup = (state = INITIAL_STATE , action) => {
  switch(action.type) {
    case types.SAVE_USER_SUCCESS:
      return { ...state, is_Active:false, isLoading: true, error: { register: action.payload }};
      case types.SAVE_USER_FAILURE:
      return { ...state, error: { register: action.payload }};
      case types.HIDE_NOTIFICATION:
      return { ...state , error:{} };
   }
      return state;
};
export default reducerSignup;

/* reducerForm.js */

const INITIAL_STATE = {
    values: {}
};
const reducerUpdate = (state = INITIAL_STATE, action) => {
    switch (action.type) {
        case types.FORM_UPDATE_VALUE:
            return Object.assign({}, state, {
                values: Object.assign({}, state.values, {
                    [action.name]: action.value,
                })
            });
        case types.FORM_RESET:
        return INITIAL_STATE;
        //here I need isLoading value from reducerRegister.js
    }
    return state;
};
export default reducerUpdate;

/* SignupForm.js */

import React, {Component}  from 'react';
import {reduxForm} from 'redux-form';
import {connect} from 'react-redux';
import map from 'lodash/map';
import timezones from '../../data/timezones';
import styles from '../formElements/formElements.scss';
import {registerUser}  from '../../actions/actionRegister';
import {formUpdate}   from '../../actions/actionForm';
import FieldGroup from '../formElements/FieldGroup';
import { Form, FormControl, Col, Checkbox, Button, FormGroup } from 'react-bootstrap';


// {... props} passing large number of props wrap in object with spread notation
class SignupForm extends Component { //if component have state it needs to be class
    constructor(props) {
        super(props);
        this.state = {
         errors: { //this errors are irrelevant for now
           name:'',
           email: '',
           password: '',
           passwordConfirmation:'',
           timezone:''
         },
       };
    }
    onChange = (event, index, value) => {
       this.props.onChange(event.target.name, event.target.value);
    };
    onSave = (event) => {
        event.preventDefault();
        this.props.onSave(this.props.values);
    }
    render() {
      let isLoading = this.props.isLoading;
        return (
                    // this.props.handleSubmit is created by reduxForm()
         // if the form is valid, it will call this.props.onSubmit
         <Form onSubmit={this.onSave} horizontal>
   <FieldGroup
     id="formControlsName"
     type="text"
     label="Name"
     name="name"
     placeholder="Enter Name"
     value={this.props.values[name]}
     onChange={this.onChange}
     help={this.state.errors.name}
   />
   <FieldGroup
     id="formControlsEmail"
     type="text"
     label="Email"
     name="email"
     placeholder="Enter Email"
     value={this.props.values[name]}
     onChange={this.onChange}
     help={this.state.errors.email}
   />
   <FieldGroup
     id="formControlsPassword"
     type="password"
     label="Password"
     name="password"
     placeholder="Enter Password"
     value={this.props.values[name]}
     onChange={this.onChange}
     help={this.state.errors.password}
   />
   <FieldGroup
     id="formControlsPasswordConfirmation"
     type="password"
     label="Password Confirmation"
     name="passwordConfirmation"
     placeholder="Enter Password"
     value={this.props.values[name]}
     onChange={this.onChange}
     help={this.state.errors.passwordConfirmation}
   />
   <FieldGroup
     id="formControlsTimezone"
     label="Time Zone"
     name="timezone"
     placeholder="Select Time Zone"
     componentClass="select"
     defaultValue="Select Your Timezone"
     value={this.props.values[name]}
     onChange={this.onChange}
     help={this.state.errors.timezone}
   >
     <option value="Select Your Timezone">Select Your Timezone</option>
       {
        map(timezones, (key, value) =>
         <option  key={key} value={key}>{value}</option>)
       }
     </FieldGroup>
   <FormGroup>
      <Col smOffset={4} sm={8}>
        <Checkbox>Remember me</Checkbox>
      </Col>
    </FormGroup>
   <FormGroup>
    <Col smOffset={4} sm={8}>
     <Button type="submit"  disabled={isLoading}
       onClick={!isLoading ? isLoading : null}
     >
     { isLoading ? 'Creating...' : 'Create New Account'}
       </Button>
   </Col>
       </FormGroup>
         {this.props.errorMessage && this.props.errorMessage.register &&
          <div className="error-container">{this.props.errorMessage.register}</div>}
   </Form>
             //this.setState({ disabled: true });
            //this.props.errorMessage.register == this.props = {errorMessage :{ register: ''}}
        );
    }
}
function mapStateToProps(state) {
    return {
        errorMessage: state.signup.error,
    isLoading: state.signup.isLoading,
    values: state.form.values

    };
}
function mapDispatchToProps(dispatch) {
  return {
   onSave: (values) => dispatch(registerUser(values)),
   onChange: (name, value) => dispatch(formUpdate(name, value))
  };
}
export default connect(mapStateToProps, mapDispatchToProps)(SignupForm)

;

【问题讨论】:

    标签: forms reactjs redux react-redux reducers


    【解决方案1】:

    没有必要使用redux-form :-) 你在正确的道路上,你在正确的地方调用FORM_RESET 操作。

    几件事:

    • 您确定要在actionRegister.js 中导入formReset 吗?
    • 在reducerForm 我建议还是在这里返回新状态:

      case types.FORM_RESET: return { ...INITIAL_STATE }; // or Object.assign({}, INITIAL_STATE)

    顺便说一句。为什么将isLoading: true 设置为成功?我建议创建 3 个动作而不是 2 个:

    • SAVE_USER_START(您在发送请求之前dispatch), 将isLoading 设置为true,
    • SAVE_USER_SUCCESS - 将 isLoading 设置为 false
    • SAVE_USER_FAILURE - 将 isLoading 设置为 false

    【讨论】:

    • 查看他的问题“只想提一下我不使用 redux-form”。他的问题的最佳答案不是“改用 redux-form”......
    • 非常感谢@szymomn,我会试试你的建议
    • @WitVault redux-form 导入是上次尝试留下的,我不再使用它,无论如何感谢您注意到,将删除该导入
    • 是的,最好删除它以避免混淆。
    【解决方案2】:

    我建议查看redux-form 库。它提供了开箱即用的提交后清除字段的配置选项。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-14
      • 1970-01-01
      • 2021-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-21
      相关资源
      最近更新 更多