输入字段不响应将状态更改为空对象

Input fields do not respond to changing state to empty object

为什么在我 post 之后,输入字段的值保持不变,即使我将数据状态更改为空? 我 console.logged 状态和 post 之后数据状态变量被正确设置为一个空对象,但输入的状态没有改变。 请指教。

var AccountView = React.createClass({

getDefaultProps: function() {
    return {
        data: {},
        users: [],
    };
},

getInitialState: function() {
    return {
        data: {},
        users: {},
    };
},

componentDidMount: function() {
    $.ajax({
        url: "/react-webpack/js/source/controllers/get_accounts.php",
        async: "false",
        dataType: "json",
        sucess: function(json) {
            console.log("success!");
            console.log(json);      

        },
        error:function(x, e) {
            alert(e);
        },
        complete: function(a, data) {
            var users = JSON.parse(a.responseText);
            this.setState({
                users: users,
            });
        }.bind(this)
    });
},

handleChange: function(e) {
    var data = this.state.data;
    data[e.target.name] = e.target.value;
    this.setState({
        data: data,
    });
},

handleSave: function(e) {
    e.preventDefault();
    var users = this.state.users;
    users.push(this.state.data);
    $.ajax({
        url: "/react-webpack/js/source/controllers/post_accounts.php",
        type: "post",
        data: this.state.data,
        success: function(data, a) {
            this.setState({
                data: {},
            });
        }.bind(this),
        error: function(e) {

        },
        complete: function(a, data) {
            this.setState({
                data: {},
                users: users,
            });
        }.bind(this)
    });
},

render: function() {
    return (
        <div className="container">
            <form method="post">    
                <dl id="form" className="row">
                    <div className="col-md-4">
                        <dt>Firstname</dt>
                        <dd>
                            <input name="firstname" type="text" value={this.state.data.firstname} onChange={this.handleChange} />
                        </dd>
                        <dt>Lastname</dt>
                        <dd>
                            <input name="lastname" type="text" value={this.state.data.lastname} onChange={this.handleChange} />
                        </dd>
                        <dt>Password</dt>
                        <dd>
                            <input name="password" type="text" value={this.state.data.password} onChange={this.handleChange} />
                        </dd>
                        <dt>Email Address</dt>
                        <dd>
                            <input name="emailaddress" type="text" value={this.state.data.emailaddress} onChange={this.handleChange} />
                        </dd>
                        <dt>Submit</dt>
                        <dd>
                            <input type="submit" value="Submit" onClick={this.handleSave} />
                        </dd>
                    </div>
                    <div className="col-md-8">
                        <table>
                            <thead>
                                <tr>
                                    <th>Firstname</th>
                                    <th>Lastname</th>
                                    <th>Password</th>
                                    <th>Email address</th>
                                </tr>
                            </thead>
                            <tbody>
                            {_.map(this.state.users, function(user) {
                            return (
                                    <tr>
                                        <td>{user.firstname}</td>
                                        <td>{user.lastname}</td>
                                        <td>{user.password}</td>
                                        <td>{user.emailaddress}</td>
                                    </tr>
                                    );  
                            })}
                            </tbody>
                        </table>
                    </div>
                </dl>
            </form>
        </div>
    );
}

});

module.exports = AccountView;

当您在输入上使用 value={this.state.data.firstname} 时,如果 this.state.data.firstname 为 null 或未定义并且已经在输入上设置了一个值,它会保留它。因此,当您将 data 设置为空对象时,所有内容都会将 null/undefined 传递给输入。

因此,当您更新状态时,不要将 data 设置为空对象,而是将所有值重置为空字符串。这样做的一个好方法是首先在 class 之外创建一个新的 initialState 变量,其中包含状态的完整形状,然后在 getInitialState 方法中使用它:

var initialState = {
    data: {
      firstname: '',
      lastname: '',
      password: '',
      emailaddress: ''
    },
    users: [] // also not this should be an array instead of an object
};

在你的 class 里面:

getInitialState: function() {
  // we're cloning initialState so it doesn't get modified directly
  // as we want to use it later to reset the state
  return Object.assign({}, initialState); 
},

接下来,不要 this.setState({ data: {} }) 而是这样做:

this.setState({
  data: Object.assign({}, initialState.data)
});

附带说明一下,您还有两个地方可以直接改变状态 - handleChangehandleSave:

handleChange: function(e) {
    var data = this.state.data;
    data[e.target.name] = e.target.value; // this is directly mutating the state
    this.setState({
        data: data,
    });
},

// ...

handleSave: function(e) {
  e.preventDefault();
  var users = this.state.users;
  users.push(this.state.data); // this is directly mutating the state
  // ...

改变 setState() 之外的状态会导致一些奇怪的意外副作用,通常是性能不佳的原因。

要修复它,首先复制状态数据,添加到它,然后设置它(只需要简单的更改):

handleChange: function(e) {
    var data = Object.assign({}, this.state.data);
    data[e.target.name] = e.target.value;
    this.setState({
        data: data,
    });
},

// ...

handleSave: function(e) {
  e.preventDefault();
  var users = this.state.users.slice();
  users.push(this.state.data);
  // ...

这是我根据 James Ganong 的工作发现的工作方式,尽管在我的工作环境中注意将状态设置为清除是没有必要的,因为问题是:空对象不清除输入不存在。

handleSave: function(e) {
    e.preventDefault();
    var users = this.state.users;
    users.push(this.state.data);
    $.ajax({
    url: "/react-webpack/js/source/controllers/post_accounts.php",
    type: "post",
    data: this.state.data,
    success: function(data, a) {
        this.setState({
            data: {},
        });
    }.bind(this),
    error: function(e) {

    },
    complete: function(a, data) {
       var clear = {
            firstname: '',
            lastname: '',
            password: '',
            emailaddress: '',
       };
       this.setState({
            data: clear,
            users: users,
        });
    }.bind(this)
});
},