专注于条件渲染react组件中的输入文本

时间:2019-07-08 18:08:31

标签: reactjs

我在reactJs中有条件渲染组件。我使用最新的React版本,并在我的应用程序中使用MaterialUi。该组件用于显示带有文本的跨度,用户单击它后,它立即变为具有MaterialUi组件的输入,用户可以通过该组件更改字段

import React from 'react';
import EditIcon from '@material-ui/icons/Edit';
import TextField from '@material-ui/core/TextField';
import { grey400 } from 'material-ui/styles/colors';

class InlineEditInput extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            hover: false,
            edit: false,
            value: this.props.children
        };

        this.textInput = React.createRef();
    }

    handleClick = event => {
        event.stopPropagation();
        if (!this.state.edit) {
            this.setState({ value: this.props.children });
            this.setState({ edit: true, hover: false });
        }
    };

    handleBlur = () => {
        this.setState({ edit: false });
        if (this.state.value.length > 0 && this.state.value !== this.props.children) this.props.onChange(this.state.value);
        else this.setState({ value: this.props.children });
    };

    handleMouseEnter = () => this.setState({ hover: true });
    handleMouseLeave = () => this.setState({ hover: false });


    render() {
        let { hover, edit, value } = this.state;
        const originalValue = this.props.children;

        const styles = {
            label: { minHeight: '2em', marginTop: '10px' },
            editIcon: { width: 20, height: 20, fill: grey400, marginLeft: 8 },
            editIconHidden: { width: 20, height: 20, fill: 'none', marginLeft: 8 }
        };
        const setFocus = () => {
            this.textInput.focus();
        };

        if (!edit)
            return (
                <div onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}>
                    <span onClick={this.handleClick}>{originalValue}</span>
                    {hover ? <EditIcon style={styles.editIcon} /> : <EditIcon style={styles.editIconHidden} />}
                </div>
            );
        else
            return (
                <TextField
                    id="EditField"
                    ref={input => {
                        this.textInput = input;
                        setFocus();
                    }}
                    value={value}
                    onClick={this.handleClick}
                    onBlur={this.handleBlur}
                    onChange={event => this.setState({ value:event.target.value })}
                />
            );
    }
}

export default InlineEditInput;

首先呈现从其组件的道具获得的值为originalvalue的跨度,然后单击此跨度,将edit状态更改为ture和一个TextField组件MaterialUi中的TextField已渲染,我想着眼于此TextField。 为此,我渲染了ref并定义了其setFocus属性,该属性将输入传递给名称为this2.textInput.focus is not a function 的函数,并在此函数中编写了focus方法。 但是,当我单击跨度并重新渲染组件时,我遇到了显示以下错误:

y

我该如何编写此组件?

1 个答案:

答案 0 :(得分:2)

尝试使用 componentDidUpdate 生命周期挂钩

componentDidUpdate(prevProps, prevState, snapshot) {
  if(this.state.edit)
    this.textInput.focus();
}

您的方法无法使输入集中的原因可能是由于在实际创建引用时尚未插入DOM。更像是创建了textInput元素,但未将其附加到DOM。只是预感,不是100%肯定。