【问题标题】:React Input losing focus after keystroke击键后反应输入失去焦点
【发布时间】:2017-08-06 07:19:41
【问题描述】:

我正在 React/Redux 中构建一个应用程序,我有一些输入字段在每次击键后失去焦点。我的代码如下所示:

<General fields={props.general}
    onChange={value => props.updateValue('general', value)} />

<FormWrapper>
    <Network fields={props.network}
        onChange={value => props.updateValue('network', value} />
    </NetworkTableForm>
</FormWrapper>

General 和 Network 只包含表单的不同部分,FormWrapper 可以包装表单的一个子部分并提供一些有趣的可视化。问题是General 中的所有字段都可以正常工作,但Network 中的字段在每次击键后都会失去焦点。我已经尝试将键附加到一堆不同的元素上,例如 General Network、FormWrapper 以及包装我的输入字段的组件,我不使用 redux-form 的原因是因为它没有与我正在使用的 UI 框架(Grommet)配合得很好。知道是什么原因造成的吗?

编辑:根据请求添加更多代码。这是完整的组件:

const InfoForm = (props) => {

    let FormWrapper = FormWrapperBuilder({
        "configLists": props.configLists,
        "showForm": props.showForm,
        "loadConfiguration": props.loadConfiguration,
        "updateIndex": props.updateIndex,
        "metadata": props.metadata})

    return (
        <CustomForm onSubmit={() => console.log('test')}
             loaded={props.loaded} heading={'System Details'}
             header_data={props.header_data}
             page_name={props.general.name} >

            <General fields={props.general}
                 onChange={(field, value) => props.updateValue('general', field, value)} />

            <FormWrapper labels={["Interface"]} fields={["interface"]} component={'network'}>
                <Network fields={props.network}
                    onChange={(field, value) => props.updateValue('network', field, value)} />
            </FormWrapper>

            <User fields={props.user}
                 onChange={(field, value) => props.updateValue('user', field, value)} />


        </CustomForm>
    )
}

export default InfoForm

这是一个表单部分组件的示例:

const Network = ({fields, onChange}) => (
    <CustomFormComponent title='Network'>
        <CustomTextInput value={fields.interface} label='Interface'
            onChange={value => onChange('interface', value)} />

        <CustomIPInput value={fields.subnet} label='Subnet'
            onChange={value => onChange('subnet', value)} />

        <CustomIPInput value={fields.network} label='Network'
            onChange={value => onChange('network', value)} />

        <CustomIPInput value={fields.gateway} label='Gateway'
            onChange={value => onChange('gateway', value)} />

        <CustomIPInput value={fields.nat_ip} label='NAT'
            onChange={value => onChange('nat_ip', value)} />
    </CustomFormComponent>
)

export default Network

以下是自定义输入之一的示例:

const CustomTextInput = ({label, value, onChange}) => (
    <FormField label={<Label size='small'>{label}</Label>}>
        <Box pad={{'horizontal': 'medium'}}>
            <TextInput placeholder='Please Enter' value={value}
                onDOMChange={event => onChange(event.target.value)}
            />
        </Box>
    </FormField>
)

export default CustomTextInput

这是 FormWrapperBuilder 函数:

const FormWrapperBuilder = (props) =>
    ({component, labels, fields, children=undefined}) =>
        <VisualForm
            configLists={props.configLists[component]}
            showForm={visible => props.showForm(component, visible)}
            loadConfiguration={index => props.loadConfiguration(component, index)}
            updateIndex={index => props.updateIndex(component, index)}
            metadata={props.metadata[component]}
            labels={labels} fields={fields} >
            {children}
        </VisualForm>

export default FormWrapperBuilder

所有这些都保存在单独的文件中,这可能会影响页面的重新呈现,并且包裹在 FormWrapper 中的函数在状态更改后会失去焦点。此外,我尝试为这些组件中的每一个添加密钥,但没有任何运气。这也是我的容器组件中的功能:

const mapDispatchToProps = (dispatch) => {
    return {
        'updateValue': (component, field, value) => {
            dispatch(updateValue(component, field, value))},

        'showForm': (component, visible) => {
            dispatch(showForm(component, visible))
        },

        'loadConfiguration': (component, index) => {
            dispatch(loadConfiguration(component, index))
        },

        'pushConfiguration': (component) => {
            dispatch(pushConfiguration(component))
        },

        'updateIndex': (component, index) => {
            dispatch(updateIndex(component, index))
        }
    }
}

编辑 2:修改了我的自定义文本输入,例如按照 Hadas 的回答。还用钥匙和参考书给它涂上了厚厚的一层,以防万一

export default class CustomTextInput extends React.Component {

    constructor(props) {
        super(props)
        this.state = {value: ""}
    }

    render() {
        return (
            <FormField key={this.props.label} ref={this.props.label} label={<Label size='small'>{this.props.label}</Label>}>
                <Box key={this.props.label} ref={this.props.label} pad={{'horizontal': 'medium'}}>
                    <TextInput placeholder='Please Enter' value={this.state.value} key={this.props.label} ref={this.props.label}
                    onDOMChange={event => { this.props.onChange(event.target.value); this.state.value = event.target.value }} />
                </Box>
            </FormField>
        )
    }
}

【问题讨论】:

  • 你能显示你的updatevalue函数吗,好像是答案的关键
  • 可以,你是指reducer中的函数还是容器中的函数?
  • 或许可以编辑您的问题,使其易于查看
  • 当然,我现在要添加更多代码
  • 已添加请求的信息。

标签: javascript reactjs redux


【解决方案1】:

React 会在每次击键时重新渲染 DOM。尝试将 value 设置为附加到组件状态的变量,如下所示:

<TextInput style={{height: 40, borderColor: 'gray', borderWidth: 1}} onChangeText={(text) => this.setState({text})} value={this.state.text}></TextInput

【讨论】:

  • 还是同样的问题吗?击键后失去焦点?或者您可以提供有关更改的任何其他信息?
  • 抱歉应该说 - 这个问题现在是我无法使用这个更新版本输入输入,这是有道理的,因为在我看来 state.value 在每次状态更改时都设置为空字符串(其中在这个组件的情况下是每次击键)。就我所有的变化而言,这就是全部。我整天都在添加和删除组件上的键和引用,并将组件从无状态更改为有状态,希望某些东西会起作用,但似乎什么也没发生。
  • 我也一直在尝试使用 shouldComponentUpdate() 和 componentWillMount() 生命周期方法来阻止组件在状态更改时更新但无济于事。我认为问题可能出在FormWrapperBuilder (因为它的组件包裹FormWrapper 失去焦点)
  • 取出裁判和钥匙。如果实施不当,可能会搞砸。也使用 onChangeText 而不是 onDOMChange。我测试了我刚刚编辑答案的 sn-p 并且它有效
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-08
相关资源
最近更新 更多