如何防止setState更改输入字段?

时间:2019-08-28 10:00:42

标签: javascript reactjs event-handling dom-events antd

我正在使用ant设计表单,并试图防止在选中复选框后清除输入。

这是代码:


this.state = {

  externalOptionsArray: [],

}

// onClick function

optionOnChange = (e, index, array) => {
        const { externalOptionsArray } = this.state

        let externalOptionCurrentState = externalOptionsArray

        externalOptionCurrentState[index].is_enabled = !externalOptionCurrentState[index].is_enabled;
        this.setState({
            externalOptionsArray: externalOptionCurrentState
        })
    }

// Components

<Form onSubmit={this.onSubmit}>

    <FormContainerWithDescription
        direction="vertical"
        title="Product"
        description="Product Information">
        <FormItemRow>
            <Col span={24} style={colStyle}>
                <FormItem label={'Product name'} colon={false} style={{ marginBottom: 0 }}>
                    {getFieldDecorator('title', {
                        rules: [
                            { required: true, message: 'name is required' },
                        ],
                    })(<Input />)}
                </FormItem>
            </Col>
        </FormItemRow>

        <FormItemRow>
                <Col span={24} style={colStyle}>
                    <FormItem label={'external_options'} colon={ false } style={{ marginBottom: 0 }}>   
                        { externalOptionsArray.map((option, index, array) => {
                            return (
                                <Col style={{ float: 'left', width: '50%' }} key={option.name}>
                                    <Row>
                                        <Checkbox defaultChecked={option.is_enabled} onChange={() => this.optionOnChange(index, array)}>{option.name}</Checkbox>
                                    </Row>
                                </Col>
                            )
                        })}
                    </FormItem>
                </Col>
            </FormItemRow>

    </FormContainerWithDescription>
</Form>

这是更好理解的图像

screen shot

问题是当我在输入字段中输入文本并单击复选框之一时,输入字段自动清除,输入字段再次变为空白。

我相信这是由于 optionOnChange 函数中的setState而发生的。每当我单击其中一个复选框时,就会发生setState并重新呈现DOM。

因此,我在复选框组件内部使用了 e.preventDefault() e.stopPropagaion ,如下所示。

<Checkbox defaultChecked={option.is_enabled} onChange={() => this.optionOnChange(index, array)} onClick={e => e.preventDefault()}>{option.name}</Checkbox>

// and

optionOnChange = (e, index, array) => {
        e.preventDefault()
        e.stopPropagation()
        const { externalOptionsArray } = this.state

        let externalOptionCurrentState = externalOptionsArray

        externalOptionCurrentState[index].is_enabled = !externalOptionCurrentState[index].is_enabled;
        this.setState({
            externalOptionsArray: externalOptionCurrentState
        })
    }

但是他们都不起作用

如何在不重新显示输入字段的情况下使Checkbox正常工作?

2 个答案:

答案 0 :(得分:0)

您可以将产品名称存储在状态中,并在输入更改时进行更改。

this.state = {
  externalOptionsArray: [],
  productName: '',
}

然后定义onChange函数,您可以在其中处理状态更新,就像在optionOnChange()中一样

并将其传递给您的输入组件

<Input onChange={this.onChange} />

答案 1 :(得分:0)

您需要将其设置为controlled component。如果使用状态变量设置Input组件的值,则即使状态更改后该值也将保留。

因此,在上面的代码中,您可能需要在状态中添加另一个变量,例如 productName ,并使用onChange事件处理程序在输入更改时设置状态

this.state = {
 externalOptionsArray: [],
 productName: '',
}

onChange = (e) => {
  this.setState({productName: e.target.value});
}

并将其传递给Input

<Input value={this.state.productName} onChange={this.onChange} />