如何保持焦点样式(已添加class)直到您在组件中单击(onBlur)

How to keep focus Style (added class) until you click out (onBlur) in a component

我正在重构和改进一个组件到 React ES6 中。基本上是一个带有样式的 div 搜索框。主要功能是当您单击 div 本身时添加一个 class 以更改样式并表明您正在聚焦它。 classnames 切换工作正常,但我必须做一些不同的事情,我必须保持焦点的样式,直到你点击退出,即使你再次点击输入。问题是,如果我再次单击搜索框本身,它会切换 class。我如何才能保持专注 class 直到用户执行 onBlur?

import React from "react";

class StatusBarSearchBox extends React.Component {

    constructor(props) {
        super(props)
        this.state = {focused: false}
        this.handleClick = this.handleClick.bind(this)
    }

    handleClick() {
        this.setState({ focused: !this.state.focused });
    }

    render() {
        var cx = require('classnames');
        var focusedConainer = cx ({
            'statusbar-searchbox-container' : true,
            'focus' : this.state.focused
        });
        var focusedIcon = cx ({
            'statusbar-searchbox-icon' : true,
            'focus' : this.state.focused
        });
        var actionButton = cx ({
            'statusbar-searchbox-action-button' : true,
            'focus' : this.state.focused
        });          

        return (
            <div className={focusedConainer} onClick={this.handleClick} onBlur={this.handleClick} >
                <div className={focusedIcon}></div>
                <input className="statusbar-searchbox-input" type="text" placeholder="BUSCAR..." />
                <div className={actionButton}></div>
            </div>
        );
    }
};

module.exports = StatusBarSearchBox;

onBlur 工作正常,除非您在搜索框上单击 2 次然后单击外部,因为它会切换样式。

您可以有条件地添加事件处理程序。

<div
  className={focusedConainer}
  onClick={!this.state.focused && this.handleClick}
  onBlur={this.state.focused && this.handleClick}
>

您还应该将 handleClick 方法重命名为 toggleFocus.

我终于得到了这个组件,它工作正常,但下一个改进是对输入进行自动对焦,即使点击外部但进入搜索框的容器 div。这可能吗??

代码如下:

import React from "react";

class StatusBarSearchBoxView extends React.Component {

    constructor(props) {
        super(props)
        this.state = {focused: false}
        this.toggleSearchBox = this.toggleSearchBox.bind(this)
        this.clickOut = this.clickOut.bind(this)
    }

    toggleSearchBox() {
        if (this.state = {focused: false}) {
            this.setState({ focused: !this.state.focused });
        } else {
            this.setState({ focused: this.state.focused });
        }
    }

    clickOut() {
        this.setState({ focused: !this.state.focused });
    }

    render() {
        var cx = require('classnames');
        var focusedConainer = cx ({
            'statusbar-searchbox-container' : true,
            'focus' : this.state.focused
        });
        var focusedIcon = cx ({
            'statusbar-searchbox-icon' : true,
            'focus' : this.state.focused
        });
        var actionButton = cx ({
            'statusbar-searchbox-action-button' : true,
            'focus' : this.state.focused
        });          

        return (
            <div className={focusedConainer} onClick={this.toggleSearchBox} onBlur={this.clickOut} >
                <div className={focusedIcon}></div>
                <input className="statusbar-searchbox-input" type="text" placeholder="BUSCAR..." />
                <div className={actionButton}></div>
            </div>
        );
    }
};

module.exports = StatusBarSearchBoxView;