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

Posted

技术标签:

【中文标题】专注于条件渲染反应组件中的输入文本【英文标题】:focus on input text in conditional rendering react component 【发布时间】:2019-11-18 07:03:36 【问题描述】:

我在reactJs 中有条件渲染组件。我使用最新的反应版本,并在我的应用程序中使用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 的span 被渲染,该span 来自它的该组件的props,通过单击它,edit 状态更改为ture,并渲染MaterialUiTextField 组件我想关注这个TextField一旦它被渲染。 为此,我渲染了一个TextField 并定义了它的ref 属性,该属性将输入传递给一个名为setFocus 的函数,在这个函数中我编写了焦点方法。 但是当我点击 span 并重新渲染组件时,我遇到了这样的错误:

this2.textInput.focus is not a function

如何编写这个组件?

【问题讨论】:

【参考方案1】:

尝试使用componentDidUpdate生命周期钩子

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

您的方法没有使输入成为焦点的原因可能是由于在您实际创建 ref 时尚未插入 DOM。更像是创建了 textInput 元素,但它没有附加到 DOM。只是预感,不是 100% 确定。

【讨论】:

以上是关于专注于条件渲染反应组件中的输入文本的主要内容,如果未能解决你的问题,请参考以下文章

jQuery专注于数组模糊

jQuery:如何专注于输入文本字段,使光标位于文本的末尾?

JavaScript jquery - 专注于页面上的第一个文本输入字段

iOS Safari(移动)和 Angular Material UI:专注于输入字段时不需要的闪烁文本

专注于我们网站上的文本框时,在 iPad 上强制使用数字键盘

为啥专注于输入框和选项不适用于引导模式?