【问题标题】:Sending data from a form to the parent component in ReactJS在 ReactJS 中将数据从表单发送到父组件
【发布时间】:2017-03-10 08:45:51
【问题描述】:

我有这个AddUser 组件,它是一个简单的组件,它从下拉列表中获取一个电子邮件地址和一个角色,然后将这两个值传递给父组件。除了一件事之外,一切都很好:如果我首先输入电子邮件地址然后选择角色onChange() 不会从下拉列表中获取值并将 null 传递给父组件。但如果我先选择角色然后输入电子邮件,onChange() 会同时获得这两个值!我该如何解决?

这个组件有 3 个属性:roles 是一个字典,我正在从它创建 rolesList 以将其用作 DropdownList 的数据(它来自 react-widgethttps://jquense.github.io/react-widgets/docs/#/?_k=3fo3eq)。第二个属性是handleChange(),它设置父组件的状态。第三个是handleAddNewUser(),它将值从表单返回到父组件。

export const AddUser = React.createClass({
    getInitialState() {
        return {
            email: "",
            selectedRole: "",
        };
    },

    onChange() {
        var email = this.email.value;
        this.props.handleChange(email, this.state.selectedRole); 
    }, 

    render() {
        var rolesList = [];
        for(var key in this.props.roles){
            rolesList.push(key);
        }
        return(
            <div >
                <form onSubmit={this.props.handleAddNewUser}>
                    <label >New user email address:</label>
                    <input ref={(ref) => this.email = ref} name='email'  type='email' onChange={this.onChange}  required />
                    <label >Choose a role for new user:</label>
                    <DropdownList data={rolesList} value={this.state.selectedRole} name='rolesList' onChange={selectedRole => this.setState({ selectedRole })} /> 
                    <button type="submit" >Add user</button>
                </form>
            </div>
        );
    },
});

更新:这是来自父组件的代码,handleChange() 设置父组件的状态。 handleAddNewUser() 应该使用状态并发出 ajax 请求来创建新用户。现在它对newUserEmail 有价值,但对newUserRole 没有价值

handleChange(email, selectedRole){
    this.setState({newUserEmail: email})
    this.setState({newUserRole: selectedRole})
},

handleAddNewUser(e) {
    e.preventDefault();
    // using its state, it supposed to make an ajax request and create a new user
    }

【问题讨论】:

    标签: javascript forms reactjs


    【解决方案1】:

    如果需要,您可以从提交处理程序中获取值。 Here is an example.

    编辑:组件DropdownList 不会创建真正的select 表单元素,它只是创建了一堆div 元素。这就是为什么普通的event.target 解决方案不起作用的原因。您确实需要组件的自定义 onChange 处理程序。试试下面的。它只会在本地设置状态,但这足以将此数据获取到任何父容器。您尚未发布 this.props.handleChange 的代码,因此无法知道它可以使用哪些参数。

    Edit2:添加了提交处理程序以使用正确的数据调用“this.props.handleChange”。

    export const AddUser = React.createClass({
           getInitialState() {
               return {
                   email: "",
                   selectedRole: "",
               };
           },
    
           onChange(e) {
             this.setState({
               [e.target.name]: e.target.value
             })
           },
    
           onSubmit(e) {
             e.preventDefault();
             this.props.handleChange(this.state.email, this.state.selectedRole)
           },
    
           render() {
               var rolesList = [];
               for(var key in this.props.roles){
                   rolesList.push(key);
               }
               return(
                   <div >
                       <form onSubmit={this.onSubmit}>
                           <label >New user email address:</label>
                           <input ref={(ref) => this.email = ref} name='email'  type='email' onChange={this.onChange}  required />
                           <label >Choose a role for new user:</label>
                           <DropdownList ref={(ref) => this.role = ref} data={rolesList} value={this.state.selectedRole} name='rolesList' onChange={selectedRole => this.setState({ selectedRole })} /> 
                           <button type="submit" >Add user</button>
                       </form>
                   </div>
               );
           },
       });
    

    请注意,this.setState({ [e.target.name]: e.target.value }) 像这样使用方括号是一种在不提前知道名称的情况下设置对象键的方法。在这种情况下,无论元素的名称 prop 是什么(电子邮件)。

    【讨论】:

    • 我刚试过。如果我写的onSubmit与您的答案完全相同,它会将电子邮件地址添加到地址栏中,而不是角色:?email=tes%40test.com。另外,我不希望这样。我需要它将数据从表单发送到父级并设置父级状态。我添加了e.preventDefault()onSubmit,它仍然抱怨不知道value 这里:const role = e.target.role.value;
    • 我忘了添加e.preventDefault() 感谢您指出这一点。在这种情况下,您需要使用与表单元素相同的名称,e.target.rolesList.value。您应该能够在作为道具传递的handleAddNewUser 方法中获取父级的状态。像data =&gt; this.setState(data) 这样的东西,如果你为父母发布代码会有所帮助。
    • 是的,这就是我所做的,只是在我之前的评论中犯了一个错误。使用 const role = e.target.rolesList.value; 返回此错误:Uncaught TypeError: Cannot read property 'value' of undefined
    • 查看了 react-widget DropdownList 组件实际上并没有创建选择框,它是一堆 div。这就是为什么这不起作用。我会更新答案。
    • 我刚刚在问题中添加了父组件方法。你能告诉我这里发生了什么吗:this.setState({ [e.target.name]: e.target.value })。没看懂
    【解决方案2】:

    只有在电子邮件输入值发生变化时,您才调用this.onChange()

    因此,即使在您键入的第一个字符上,this.onChange 也会发送电子邮件值,而this.role.value 则是''

    所以添加一个if() 来检查role 是否具有有效值。

    onChange() 中检查role.value

    if(email.length > 0 && role.length > 0)
        this.props.handleChange(email, role);
    

    【讨论】:

    • 问题是它不理解this.role.value,我收到了这个错误:Uncaught TypeError: Cannot read property 'value' of undefined
    猜你喜欢
    • 2016-03-18
    • 2017-09-13
    • 1970-01-01
    • 2020-09-28
    • 1970-01-01
    • 2019-09-07
    • 2018-07-07
    相关资源
    最近更新 更多