为什么React重置/重新呈现形式为

时间:2017-09-14 17:14:58

标签: reactjs react-redux redux-thunk

我有以下表格:

import React from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import {apiUpdateUser} from '../../redux/actions/user';

class EditUser extends React.Component {

  constructor(props) {
    super(props);
    this.onSubmit = this.onSubmit.bind(this);
    this.onChange = this.onChange.bind(this);
  };

  onSubmit(e) {
    e.preventDefault();
    this.props.apiUpdateUser('/users_api/users/edit-user', this.state, true);
  };

  onChange(e) {
    const target = e.target;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    const name = target.name;
    this.setState({[name]: value});
  };

  render() {
    const btnText = 'Submit'
    return (
      <div>
        <h2>Edit My Details</h2>
        <form onSubmit={this.onSubmit}>
          <div>
            <label htmlFor="inputEmail" className="sr-only">Email</label>
            <input 
              type="email" 
              name="username" 
              id="inputEmail" 
              placeholder="Email address" 
              onChange={this.onChange} 
              required 
              autoFocus 
            />
          </div>

          <div>
            <label htmlFor="inputName" className="sr-only">Name</label>
            <input 
              type="text" 
              name="name" 
              id="inputName" 
              placeholder="Users First Name" 
              onChange={this.onChange}  
              autoFocus 
            />
          </div>

          <div>
            <label htmlFor="pw-new" className="sr-only">New Password</label>
            <input 
            type="password" 
            name="passwordNew" 
            id="pw-new"  
            placeholder="Password" 
            onChange={this.onChange} 
          />
          </div>

          <div>
            <label htmlFor="pw-confirm" className="sr-only">Password Confirmation</label>
            <input 
            type="password" 
            name="passwordConfirm" 
            id="pw-confirm"  
            placeholder="Password Confirmation" 
            onChange={this.onChange} 
          />
          </div>

          <div>
            <br />
            <label htmlFor="password" className="sr-only">Current Password</label>
            <input 
            type="password" 
            name="password" 
            id="password"  
            placeholder="Current Password" 
            onChange={this.onChange} 
            required 
          />
          </div>

          <button type="submit" disabled={this.props.status === 'updating...'}>{btnText}</button>
        </form>
        <div>{this.props.status}</div>
      </div>
    )
  };
};



const mapStateToProps = (state) => {
  return {
    status: state.user.status
  };
};

const mapDispatchToProps = (dispatch) => {
  return bindActionCreators({apiUpdateUser}, dispatch);
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(EditUser);

提交后,return {...state, status: action.msg}在api请求中调用以下代码(dispatch)以更新state,更新显示错误消息的div。如果我只是在此处返回未修改的state,则表单不会按预期重新呈现。失去我的是为什么整个组件重新渲染而不仅仅是this.props.status的div。

我正在尝试做的是在发生错误并更新status时阻止组件/表单重新呈现。由于statusstate的一部分,因此当status state部分更改为reducer时,它会重新呈现整个form,而不仅仅是status div {1}}。

我尝试将唯一key添加到formstatus div。我尝试将status div作为单独的组件,并将status作为props传递。我试过shouldComponentUpdate,我唯一能做的就是不要更新状态。

如何在更新状态时阻止表单重新呈现?我使用redux-thunk并做出错误的反应吗?

注意作为解决方法,我将this.state = {status: ''}添加到构造函数中,将apiUpdateUser更改为承诺并将其从mapDispatchToProps中删除。在promise解析时,我更新了页面上的状态,如果没有错误,我调用一个动作来更新用户,因为如果没有错误,重新渲染就可以了。我只是不确定为什么我的原始方法没有按预期工作。

1 个答案:

答案 0 :(得分:0)

您的整个EditUser组件订阅了Redux状态,当状态发生变化时,整个组件将被重新呈现。这就是连接组件的工作原理。如果您不希望重新呈现整个表单,只需将提交按钮和按钮下方的div放在一个组件中,并使组件成为订阅状态状态的连接组件,不要使用无论如何,在其他地方的国家。