首页 > 解决方案 > onBlur 事件不允许链接点击注册

问题描述

我有一个导航栏,React-InstantSearch: <SearchBox />它为我提供了自动完成功能,onChange触发了一个显示建议框的事件。当您离开搜索框并隐藏该框时,还会触发一个onBlur事件。此onBlur事件阻止触发链接点击。(通过删除它来验证)。有人对我如何纠正这个有建议吗?下面的代码:

Relevant Portion of App.js

render() {
    if (this.state.redirect) {
      return (
        <div className="App-container">
          <InstantSearch
            appId="{MY APP ID}"
            apiKey={process.env.REACT_APP_ALGOLIA_API_KEY}
            indexName="blog_posts"
          >
            <NavigationBar
              loggedIn={this.state.loggedIn}
              handleLogout={this.handleLogout}
              username={this.state.username}
            />
            <Redirect to="/" />;
          </InstantSearch>
        </div>
      );
    }

    return (
      <div className="App-container">
        <InstantSearch
          appId="{MY APP ID}"
          apiKey={process.env.REACT_APP_ALGOLIA_API_KEY}
          indexName="blog_posts"
        >
          <NavigationBar
            loggedIn={this.state.loggedIn}
            handleLogout={this.handleLogout}
            username={this.state.username}
          />
          <Switch>
            <Route exact path="/" />
            <Route path="/posts" component={PostListView} />
            <Route
              path="/post/:postID"
              render={props => (
                <PostDetailView
                  {...props}
                  loggedIn={this.state.loggedIn}
                  username={this.state.username}
                  deleteComment={this.deleteComment}
                />
              )}
            />
            <Route
              path="/login"
              render={props => (
                <LoginForm {...props} handleLogin={this.handleLogin} />
              )}
            />
          </Switch>
        </InstantSearch>
      </div>
    );
  }
}

export default App;

NavigationBar.js

import React, { Component } from "react";
import { Navbar, Nav, NavItem } from "react-bootstrap";
import { Link } from "react-router-dom";
import PropTypes from "prop-types";
import { Hits, SearchBox, Highlight } from "react-instantsearch-dom";

import CompanyHeader from "../config/settings.js";

/**
 * Navigation Bar for App
 * Utilizes react-bootstrap
 * @extends Component
 */
class NavigationBar extends Component {
  constructor(props) {
    super(props);
    this.state = {
      hitResultsShown: false
    };

    this.onChange = this.onChange.bind(this);
    this.onBlur = this.onBlur.bind(this);
  }

  onChange() {
    this.setState({
      hitResultsShown: true
    });
  }

  onBlur(e) {
    this.setState({
      hitResultsShown: false
    });
    e.target.value = "";
  }

  render() {
    const logged_in_nav = (
      <React.Fragment>
        <NavItem eventKey={2} href="#">
          {`Hello, ${this.props.username}`}
        </NavItem>
        <NavItem eventKey={3} onClick={this.props.handleLogout}>
          Logout
        </NavItem>
      </React.Fragment>
    );

    const logged_out_nav = (
      <React.Fragment>
        <NavItem eventKey={2} href="/login">
          Log In
        </NavItem>
        <NavItem eventKey={3} href="/signup">
          SignUp
        </NavItem>
      </React.Fragment>
    );

    return (
      // Instantiate a Navbar with:
      //   Dark Theme
      //   Full-width
      //   sticks to top of viewport
      <Navbar inverse fluid fixedTop>
        <Navbar.Header>
          <Navbar.Brand>
            <a href="/">{CompanyHeader}</a>
          </Navbar.Brand>
          <Navbar.Toggle />
        </Navbar.Header>
        <Navbar.Collapse>
          <Nav>
            <NavItem eventKey={1} href="/random">
              Random Post
            </NavItem>
            {this.props.loggedIn ? logged_in_nav : logged_out_nav}
          </Nav>

          <Navbar.Form pullRight>
            <SearchBox onChange={this.onChange} onBlur={this.onBlur} />
            {this.state.hitResultsShown ? <Hits hitComponent={PostHits} /> : ""}
          </Navbar.Form>
        </Navbar.Collapse>
      </Navbar>
    );
  }
}

class PostHits extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    const hit = this.props.hit;
    return (
      <div>
        <span className="hit-name">
          <Link to={`/post/${hit.id}`}>
            <Highlight attribute="title" hit={hit} className="font--bold" />
          </Link>
        </span>
        <p className="well">
          {hit.content.length > 100 ? hit.content.slice(0, 100) : hit.content}
        </p>
      </div>
    );
  }
}

标签: javascriptreactjsevents

解决方案


发生这种情况是因为您的 onBlur 仅包装了 Searchbox 组件。

当您单击建议框链接时,您正在从搜索框中移除焦点并随后隐藏建议。

您所要做的就是将两个元素都包装在 onBlur 中,您的问题就会得到解决:

<div onFocus={this.onChange} onBlur={this.onBlur} >
  <SearchBox />
  {this.state.hitResultsShown && <Hits hitComponent={PostHits} />}
</div>

注意:内联条件渲染更好的是 ^ 和 onFocus 会调用一次,而不是像 onChange 那样重复调用。

在这种情况下,您的建议框通常是搜索组件的一部分,因为它本质上是链接的,将模糊/更改功能向下推到该组件中,并使其更加独立。


推荐阅读