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

本文探讨了在React项目中处理配置项模块的数据加载问题,特别是在只有一个配置页面且无列表或增删功能的情况下,如何避免数据更新冲突。通过引入加载状态标志位控制渲染流程,确保在数据加载完成后正确更新表单组件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们知道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
            })
        })
    }

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值