关于react在componentDidMount中请求之后的数据无法更新表单的问题

我们知道componentDidMount会在render函数执行之后即组件渲染之后执行。那么需要去后台准备数据的时候比如说获取list列表时,会在componentDidMount中去后台请求数据,然后更新到表单中。

但是在做react项目时,碰到配置项的模块(只有一个配置页面,没有list页面以及增删页面),会出现问题。

配置项一般会去检查输入的合法与否,所以我们一般会采用antd的form表单去做。需要通过this.state.item去绑定初始值,当页面渲染之后,调用componentDidMount时,请求返回数据再去更新数据就会出现数据更新不了的情况。

所以一般碰到这种问题,我们都会使用一个标志位来控制render函数的渲染,只有当componentDidMount中的请求返回时,我们才去设置标志位,去渲染form表单这就跟初始化一样。

比如:

在项目初始化的时候,我会在页面设置一些默认值

constructor(props) {
        super(props);
        this.state = {
            periodUnit: "Hour(s)",
            rememberDevice: true,
            expireFlag: 0,
            deviceValidityPeriod: 30,
            maxDeviceNumberPerAccount: 5,
            deviceMin: 1,
            deviceMax: 365,
            maxDeviceNumberPerAccountMin: 1,
            maxDeviceNumberPerAccountMax: 10,
            periodUnitArry: ["Day(s)", "Hour(s)", "Minute(s)"],
            loadding: false
        }
    }

我们知道,constructor是在组件生成的时候首先回去执行的函数,它肯定是在render之前,这么设置数据显示也是没有问题的。

<Form {...formItemLayout} labelAlign="right">
                                <Collapse accordion expandIconPosition="right" defaultActiveKey={['2']} className="samp_collapse_style">
                                    <Panel header={intl.get("samp.byodManagement.byodGlobalConfiguration.panel.registrationStrategy")} key="2" className="samp_collapse_panel_header">
                                        <Form.Item label={intl.get("samp.byodManagement.byodGlobalConfiguration.item.periodUnit")} validateStatus={periodUnitError ? 'error' : ''} help={periodUnitError || ''}>
                                            {getFieldDecorator('periodUnit', { initialValue: this.state.periodUnit, rules: rules.periodUnit })(
                                                <Select
                                                    onChange={this.changePeriodUnit}
                                                    placeholder={intl.get("samp.common.pleaseSelect")}
                                                >
                                                    {
                                                        this.state.periodUnitArry && this.state.periodUnitArry.map((item) => {
                                                            return <Option value={item} key={item}>{item}</Option>
                                                        })
                                                    }
                                                </Select>)}
                                        </Form.Item>
                                        <Form.Item label={intl.get("samp.byodManagement.byodGlobalConfiguration.item.rememberDevice")} validateStatus={rememberDeviceError ? 'error' : ''} help={rememberDeviceError || ''}>
                                            {getFieldDecorator('rememberDevice', { initialValue: this.state.rememberDevice, rules: rules.rememberDevice })(
                                                <Switch checkedChildren="Enabled" unCheckedChildren="Disabled" defaultChecked onChange={this.changeRememberDevice} />
                                            )}
                                        </Form.Item>
                                        {
                                            this.state.rememberDevice ?
                                                <div>
                                                    <Form.Item label={intl.get("samp.byodManagement.byodGlobalConfiguration.item.expireFlag")} hasFeedback validateStatus={expireFlagError ? 'error' : ''} help={expireFlagError || ''}>
                                                        {getFieldDecorator('expireFlag', { initialValue: this.state.expireFlag, rules: rules.expireFlag })(
                                                            <Radio.Group style={{ float: "left" }} onChange={this.changeExpireFlag}>
                                                                <Radio value={-1}>{intl.get("samp.byodManagement.byodGlobalConfiguration.item.neverExpire")}</Radio>
                                                                <Radio value={0}>{intl.get("samp.byodManagement.byodGlobalConfiguration.item.customization")}</Radio>
                                                            </Radio.Group>
                                                        )}
                                                    </Form.Item>
                                                    {
                                                        this.state.expireFlag === 0 ?
                                                            <div>
                                                                <Form.Item label={intl.get("samp.byodManagement.byodGlobalConfiguration.item.deviceValidityPeriod")} hasFeedback validateStatus={deviceValidityPeriodError ? 'error' : ''} help={deviceValidityPeriodError || ''}>
                                                                    {getFieldDecorator('deviceValidityPeriod', { initialValue: this.state.deviceValidityPeriod, rules: rules.deviceValidityPeriod })(
                                                                        <InputNumber style={{ width: "100%" }} min={this.state.deviceMin} max={this.state.deviceMax} />
                                                                    )}
                                                                </Form.Item>
                                                                <Form.Item label={
                                                                    <span>
                                                                        <Tooltip title={intl.get("samp.byodManagement.byodGlobalConfiguration.tips.maxDeviceNumberPerAccount")}>
                                                                            <Icon type="question-circle-o" />
                                                                        </Tooltip> {intl.get("samp.byodManagement.byodGlobalConfiguration.item.maxDeviceNumberPerAccount")}
                                                                    </span>} hasFeedback validateStatus={maxDeviceNumberPerAccountError ? 'error' : ''} help={maxDeviceNumberPerAccountError || ''}>
                                                                    {getFieldDecorator('maxDeviceNumberPerAccount', { initialValue: this.state.maxDeviceNumberPerAccount, rules: rules.maxDeviceNumberPerAccount })(
                                                                        <InputNumber style={{ width: "100%" }} min={this.state.maxDeviceNumberPerAccountMin} max={this.state.maxDeviceNumberPerAccountMax} />
                                                                    )}
                                                                </Form.Item>
                                                            </div> : ""
                                                    }
                                                </div> : ""
                                        }
                                    </Panel>
                                </Collapse>
                                <div className="samp_panel_from_footer">
                                    <div className="samp_panel_from_footer_button">
                                        <Button type="primary" onClick={this.apply} htmlType="submit" disabled={hasErrors(getFieldsError())} disabled={hasErrors(getFieldsError())}>
                                            {intl.get("samp.button.apply")}
                                        </Button>
                                        <Button type="primary" onClick={this.cancel} className="samp_panel_from_footer_button_cancle">{intl.get("samp.button.cancel")}</Button>
                                    </div>
                                </div>
                            </Form>

这里通过initialValue去绑定state中的属性。

然后会在

componentDidMount() {
        // 对于隐藏域的校验,目前还存在问题,先实现功能,后期优化打开初始化校验
        this.props.form.validateFields();
        this.getGlobalConfiguration()

    }

获取配置之后会去setState属性

 //获取global配置
    getGlobalConfiguration = () => {
      
        byodGlobalConfigurationService.getConfiguration().then((response) => {
            console.log(response.data[0])
            this.setState({
                // periodUnit: response.data[0].periodUnit,
                periodUnit: "Hour(s)",
                expireFlag: response.data[0].expireFlag,
                deviceValidityPeriod: response.data[0].deviceValidityPeriod,
                maxDeviceNumberPerAccount: response.data[0].maxDeviceNumberPerAccount
            })
            response.data[0].rememberDevice === "Enabled" ? this.setState({ rememberDevice: true }) : this.setState({ rememberDevice: false })
            
        })
    }

其实设置时不会生效的。

那么怎么处理呢?

增加一个标志位loadding,初始值为false,那么在这里就不会去渲染form

{
                        this.state.loadding ?
                            <Form {...formItemLayout} labelAlign="right">
                                <Collapse accordion expandIconPosition="right" defaultActiveKey={['2']} className="samp_collapse_style">
                                    <Panel header={intl.get("samp.byodManagement.byodGlobalConfiguration.panel.registrationStrategy")} key="2" className="samp_collapse_panel_header">
                                        <Form.Item label={intl.get("samp.byodManagement.byodGlobalConfiguration.item.periodUnit")} validateStatus={periodUnitError ? 'error' : ''} help={periodUnitError || ''}>
                                            {getFieldDecorator('periodUnit', { initialValue: this.state.periodUnit, rules: rules.periodUnit })(
                                                <Select
                                                    onChange={this.changePeriodUnit}
                                                    placeholder={intl.get("samp.common.pleaseSelect")}
                                                >
                                                    {
                                                        this.state.periodUnitArry && this.state.periodUnitArry.map((item) => {
                                                            return <Option value={item} key={item}>{item}</Option>
                                                        })
                                                    }
                                                </Select>)}
                                        </Form.Item>
                                        <Form.Item label={intl.get("samp.byodManagement.byodGlobalConfiguration.item.rememberDevice")} validateStatus={rememberDeviceError ? 'error' : ''} help={rememberDeviceError || ''}>
                                            {getFieldDecorator('rememberDevice', { initialValue: this.state.rememberDevice, rules: rules.rememberDevice })(
                                                <Switch checkedChildren="Enabled" unCheckedChildren="Disabled" defaultChecked onChange={this.changeRememberDevice} />
                                            )}
                                        </Form.Item>
                                        {
                                            this.state.rememberDevice ?
                                                <div>
                                                    <Form.Item label={intl.get("samp.byodManagement.byodGlobalConfiguration.item.expireFlag")} hasFeedback validateStatus={expireFlagError ? 'error' : ''} help={expireFlagError || ''}>
                                                        {getFieldDecorator('expireFlag', { initialValue: this.state.expireFlag, rules: rules.expireFlag })(
                                                            <Radio.Group style={{ float: "left" }} onChange={this.changeExpireFlag}>
                                                                <Radio value={-1}>{intl.get("samp.byodManagement.byodGlobalConfiguration.item.neverExpire")}</Radio>
                                                                <Radio value={0}>{intl.get("samp.byodManagement.byodGlobalConfiguration.item.customization")}</Radio>
                                                            </Radio.Group>
                                                        )}
                                                    </Form.Item>
                                                    {
                                                        this.state.expireFlag === 0 ?
                                                            <div>
                                                                <Form.Item label={intl.get("samp.byodManagement.byodGlobalConfiguration.item.deviceValidityPeriod")} hasFeedback validateStatus={deviceValidityPeriodError ? 'error' : ''} help={deviceValidityPeriodError || ''}>
                                                                    {getFieldDecorator('deviceValidityPeriod', { initialValue: this.state.deviceValidityPeriod, rules: rules.deviceValidityPeriod })(
                                                                        <InputNumber style={{ width: "100%" }} min={this.state.deviceMin} max={this.state.deviceMax} />
                                                                    )}
                                                                </Form.Item>
                                                                <Form.Item label={
                                                                    <span>
                                                                        <Tooltip title={intl.get("samp.byodManagement.byodGlobalConfiguration.tips.maxDeviceNumberPerAccount")}>
                                                                            <Icon type="question-circle-o" />
                                                                        </Tooltip> {intl.get("samp.byodManagement.byodGlobalConfiguration.item.maxDeviceNumberPerAccount")}
                                                                    </span>} hasFeedback validateStatus={maxDeviceNumberPerAccountError ? 'error' : ''} help={maxDeviceNumberPerAccountError || ''}>
                                                                    {getFieldDecorator('maxDeviceNumberPerAccount', { initialValue: this.state.maxDeviceNumberPerAccount, rules: rules.maxDeviceNumberPerAccount })(
                                                                        <InputNumber style={{ width: "100%" }} min={this.state.maxDeviceNumberPerAccountMin} max={this.state.maxDeviceNumberPerAccountMax} />
                                                                    )}
                                                                </Form.Item>
                                                            </div> : ""
                                                    }
                                                </div> : ""
                                        }
                                    </Panel>
                                </Collapse>
                                <div className="samp_panel_from_footer">
                                    <div className="samp_panel_from_footer_button">
                                        <Button type="primary" onClick={this.apply} htmlType="submit" disabled={hasErrors(getFieldsError())} disabled={hasErrors(getFieldsError())}>
                                            {intl.get("samp.button.apply")}
                                        </Button>
                                        <Button type="primary" onClick={this.cancel} className="samp_panel_from_footer_button_cancle">{intl.get("samp.button.cancel")}</Button>
                                    </div>
                                </div>
                            </Form> : ""
                    }

当请求数据回来的时候设置setState之后在将loadding值设置为true,由于state发生变化,回去重新渲染

//获取global配置
    getGlobalConfiguration = () => {
        this.setState({
            loadding: false
        })
        byodGlobalConfigurationService.getConfiguration().then((response) => {
            console.log(response.data[0])
            this.setState({
                // periodUnit: response.data[0].periodUnit,
                periodUnit: "Hour(s)",
                expireFlag: response.data[0].expireFlag,
                deviceValidityPeriod: response.data[0].deviceValidityPeriod,
                maxDeviceNumberPerAccount: response.data[0].maxDeviceNumberPerAccount
            })
            response.data[0].rememberDevice === "Enabled" ? this.setState({ rememberDevice: true }) : this.setState({ rememberDevice: false })
            this.setState({
                loadding: true
            })
        })
    }

这样就可以显示设置之后的值

首先,在React,你需要使用 `axios` 或者 `fetch` 等库来发起 AJAX 请求。 1. 安装 `axios` 库 在终端运行以下命令来安装 `axios` 库: ``` npm install axios ``` 2. 发起 AJAX 请求React 组件,你可以在表单提交时发起 AJAX 请求。例如: ```jsx import React, { useState } from 'react'; import axios from 'axios'; function Form() { const [formData, setFormData] = useState({ name: '', email: '', message: '' }); const handleSubmit = async (e) => { e.preventDefault(); try { const response = await axios.post('/api/contact', formData); console.log(response.data); } catch (err) { console.error(err); } } const handleChange = (e) => { setFormData({ ...formData, [e.target.name]: e.target.value }); } return ( <form onSubmit={handleSubmit}> <div> <label htmlFor="name">Name:</label> <input type="text" name="name" id="name" value={formData.name} onChange={handleChange} /> </div> <div> <label htmlFor="email">Email:</label> <input type="email" name="email" id="email" value={formData.email} onChange={handleChange} /> </div> <div> <label htmlFor="message">Message:</label> <textarea name="message" id="message" value={formData.message} onChange={handleChange}></textarea> </div> <button type="submit">Submit</button> </form> ); } export default Form; ``` 这里我们定义了一个表单组件,其包含 `name`,`email` 和 `message` 三个表单项。在 `handleSubmit` 函数,我们使用 `axios.post` 发起 POST 请求,将表单数据作为请求体传递给后端 `/api/contact` 接口。如果请求成功,我们在控制台打印服务器返回的数据。 3. 处理后端请求 在后端,你需要使用一个路由处理 POST 请求,并将表单数据存储到数据。例如,如果你使用 Node.js 和 Express 构建后端,可以使用以下代码: ```javascript const express = require('express'); const bodyParser = require('body-parser'); const app = express(); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); app.post('/api/contact', (req, res) => { const { name, email, message } = req.body; // 这里可以连接数据库,将表单数据存储到数据 // ... res.status(200).json({ success: true }); }); app.listen(3000, () => console.log('Server is running on port 3000')); ``` 这里我们使用 `body-parser` 间件来解析请求的 JSON 数据。在 `/api/contact` 路由,我们从请求获取表单数据,并将其存储到数据。如果存储成功,我们返回一个包含 `success: true` 的 JSON 响应。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值