onBlur事件不允许链接点击注册

时间:2018-09-19 23:44:13

标签: javascript reactjs events

我有一个带有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>
    );
  }
}

1 个答案:

答案 0 :(得分:1)

之所以会这样,是因为您的onBlur仅包装了Searchbox组件。

点击“建议”框链接时,您将焦点从搜索框中移出,随后隐藏了建议。

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

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

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

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