【问题标题】:React submitting data with child component state用子组件状态响应提交数据
【发布时间】:2020-09-26 22:28:28
【问题描述】:

我目前正在研究 React,我对如何为我的项目组织组件的布局有疑问。所以,基本上我有一个父组件和两个子组件。我能够将状态发送到父组件并尝试将数据(从子组件接收)提交到数据库。该按钮位于父组件上。但是每当我提交数据时,它都会发送我之前提交的数据。我将绘制我所做的逻辑并将其发布在此问题下方。

注意
通过 props 从父级向子级发送函数,并在选择框或下拉菜单上调用 onchange 后调用子级上的道具。 onchange 会先设置 state 并调用 props。

我是新手,所以请告诉我是否有更好的布局。我愿意从错误中吸取教训。

(父组件)

class Vten extends Component {

constructor(props) {
    super(props);
    this.state = {
        cbValue: "",
        cValue: ""
      }
}

handleClick = (event) => {
    event.preventDefault(); 
    var passOne = this.state.cbValue;
    var passTwo = this.state.cValue;
    const data = {passOne,passTwo};
    const options = {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(data)
    }
    fetch('/api/vten',options);
}

handleInputValue = (val, val2) => {
     alert(val);
     alert(val2);
    this.setState({ 
        cbValue: val,
        cValue: val2
    });
}

render(){
    return(
        <div>
            <Container>
                <Row>
                    <Col><h3>V-10 - Vendor / Partner / Client Registration</h3></Col>
                </Row>

                <Row>
                    <Col>
                        <VtenTwo handleInput={this.handleInputValue}/>
                    </Col>
                </Row>

                <Row>
                    <Col>
                        <Button variant="primary" type="submit">
                            Save for Later
                        </Button>
                    </Col>
                    <Col>
                        <Button variant="primary" type="submit" onClick={this.handleClick}>
                            Submit for Review
                        </Button>
                    </Col>
                </Row>
            </Container>
        </div>
    );
}
}

export default Vten;

(子组件)

class VtenTwo extends Component {

constructor(props) {
    super(props);
    this.state = {
        checkVendor: true,
        checkPartner: false,
        checkClient: false,
        checkBoxValue: "checkVendor",
        CountryDropdown: "USA"
      }
}

onCheckChange = (e) =>{
    if("checkVendor" === e.target.name){
        this.setState({
            checkVendor: true,
            checkPartner: false,
            checkClient: false,
            checkBoxValue: e.target.value
        })
    }else if("checkPartner" === e.target.name){
        this.setState({
            checkVendor: false,
            checkPartner: true,
            checkClient: false,
            checkBoxValue: e.target.value
        })
    }else{
        this.setState({
            checkVendor: false,
            checkPartner: false,
            checkClient: true,
            checkBoxValue: e.target.value
        })
    } 
    //this.props.handleInput(this.state.checkBoxValue);
    this.changedValue();
}

handleCountryChange = e => {
    this.setState({
        CountryDropdown: e.target.value
    })
    //this.props.handleInput2(this.state.CountryDropdown);
    this.changedValue();
}

//this is called from save button(child) and call function on parent
changedValue = () => {
    let ck = this.state.checkBoxValue;
    let dp = this.state.CountryDropdown;
    this.props.handleInput(ck,dp);
}

render(){
    return(
        <div>
             <label>
               <b>Step 2. Enter Entity Information</b>
            </label> <br/>

            <label>General Information</label> <br/>
            <label><b>{this.state.checkBoxValue}</b></label><br/>
            <label><b>{this.state.CountryDropdown}</b></label><br/>
            <Container>
                <Row>
                    <Col>
                        <label>Select Account Type</label>
                        <div className="radio">
                            <Form.Check inline label="Vendor" type="checkbox" name="checkVendor" value="Vendor" checked={this.state.checkVendor} onChange={this.onCheckChange} />
                            <Form.Check inline label="Partner" type="checkbox" name="checkPartner" value= "Partner" checked={this.state.checkPartner} onChange={this.onCheckChange}/>
                            <Form.Check inline label="Client" type="checkbox" name="checkClient" value= "Client" checked={this.state.checkClient} onChange={this.onCheckChange}/>                   
                        </div>
                    </Col>
                    <Col>
                        <label>Country</label>
                        <Form.Group controlId="exampleForm.ControlSelect1">
                            <Form.Control as="select" value={this.state.CountryDropdown} onChange={this.handleCountryChange}>
                                {/* <option value="">None</option> */}
                                <option value="USA">USA</option>
                                <option value="KOREA">KOREA</option>
                                <option value="JAPAN">JAPAN</option>
                            </Form.Control>
                        </Form.Group>
                    </Col>
                    {/* <Col>
                        <Button variant="primary" type="submit" onClick={this.changedValue}>
                            Save
                        </Button>
                    </Col> */}
                </Row>
            </Container>


        </div>
    );
}
 }

 export default VtenTwo;

【问题讨论】:

    标签: javascript reactjs components state onchange


    【解决方案1】:

    你可以从 React 官方文档中参考这里: https://reactjs.org/docs/lifting-state-up.html#lifting-state-up

    提升孩子的状态是一种可能的解决方案:
    1. 在父项而不是子项中定义您的状态
    2. 将状态作为道具传递给您的孩子。
    3. 在 parent 中设置状态,如果您的孩子需要设置状态,请将您的设置状态功能也通过 props 传递给您的孩子。
    4.设置状态后,你的父母会重新渲染,你的孩子也会因为道具值改变而重新渲染

    您提到的发送之前的数据,很可能与错误的状态处理有关。在此处分享您的代码可以更好地解决您的问题。

    【讨论】:

    • 您好,感谢您对我的问题的回复。正如你所说,我会看看你发给我的链接,我也上传了上面的代码。再次感谢您
    【解决方案2】:

    您正在获取之前的状态,因为 setState 是一个异步函数,并且您尝试在将状态数据设置为状态之前获取状态数据。

    您可以在 setState 中使用回调来等待状态更新,然后再调用其他函数将解决您的问题。

        onCheckChange = (e) =>{
            if("checkVendor" === e.target.name){
                this.setState({
                    checkVendor: true,
                    checkPartner: false,
                    checkClient: false,
                    checkBoxValue: e.target.value
                }, () => {
                     this.changedValue();
                })
            }else if("checkPartner" === e.target.name){
                this.setState({
                    checkVendor: false,
                    checkPartner: true,
                    checkClient: false,
                    checkBoxValue: e.target.value
                }, () => {
                    this.changedValue();
                })
            }else{
                this.setState({
                    checkVendor: false,
                    checkPartner: false,
                    checkClient: true,
                    checkBoxValue: e.target.value
                }, () => {
                   this.changedValue();
                })
            }
    
        }
    
        handleCountryChange = e => {
            this.setState({
                CountryDropdown: e.target.value
            }, () => {
               this.changedValue();
            });
    
        }
    

    【讨论】:

    • 非常感谢您的帮助。我被困了好几天试图弄清楚。我向你学习,再次感谢你。
    猜你喜欢
    • 2020-07-10
    • 2012-06-01
    • 2021-12-20
    • 2017-02-26
    • 2020-01-23
    • 2016-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多