与参数反应路由器dom链接始终无法正常工作

时间:2019-02-25 13:56:05

标签: reactjs react-router react-router-v4 react-router-dom

我编写了一个简单的搜索组件,在响应中带有自动建议,它调用themoviedb。我正在使用react-router-dom,并在app.js中定义了这样的路由参数:

<Route path="/:id" component={SomeComponent} />

,搜索组件如下所示:

import React, { Component, Fragment } from "react";
import { Link } from "react-router-dom";
import styled from "styled-components";
import axios from "axios";

const SuggestionsResult = styled.ul`
  text-decoration: none;
  list-style: none;
  text-align: left;
  display: flex;
  flex-direction: column;
  width: 100%;
`;

const ResultItem = styled.li`
  border-bottom: 0.0625rem solid hsla(0, 0%, 100%, 0.12);
  padding: 10px 0 10px;
  padding-left: 2px;
  font-size: 1em;
  cursor: pointer;
  &:hover {
    background: hsla(0, 0%, 100%, 0.12);
  }
`;

export default class Search extends Component {
  state = {
    query: "",
    results: [],
    showSuggestions: false
  };

  handleInputChange = () => {
    this.setState(
      {
        query: this.search.value
      },
      () => {
        if (this.state.query && this.state.query.length > 1) {
          if (this.state.query.length % 2 === 0) {
            axios
              .get(
                `https://api.themoviedb.org/3/search/movie?api_key=${apiKey}&language=en-US&query=${
                  this.state.query
                }&page=1&include_adult=false`
              )
              .then(({ data }) => {
                this.setState({
                  results: data.results,
                  showSuggestions: !this.state.showSuggestions
                });
              });
          }
        } else if (!this.state.query) {
        }
      }
    );
  };



  handleSuggestionClick = e => {
    this.setState({ showSuggestions: false });
  };

  render() {
    return (
      <Fragment>
        <input
          placeholder="Search for a movie..."
          ref={input => (this.search = input)}
          onChange={this.handleInputChange}
        />
        {this.state.showSuggestions && (
          <Suggestions
            results={this.state.results}
            handleSuggestionClick={this.handleSuggestionClick}
          />
        )}
      </Fragment>
    );
  }
}

const Suggestions = ({ results, handleSuggestionClick }) => {
  const options = results.map(r => (
    <ResultItem key={r.id}>
      <Link onClick={handleSuggestionClick} to={`/${r.id}`}>
        {r.title}
      </Link>
    </ResultItem>
  ));
  return <SuggestionsResult>{options}</SuggestionsResult>;
};

我的问题是,单击链接时它会更改URL,但它会保留在同一站点上。如果我不使用react-router-dom链接组件,而只使用一个元素,则效果很好,但一切都会重新呈现。

**更新 我在app.js中的react-router代码

<Router>
  <Switch>
        <Route exact path="/" component={MoviesList} />
        <Route path="/:id" component={MovieDetail} />
   </Switch>
</Router>

1 个答案:

答案 0 :(得分:2)

建议组件未收到路由器道具,因此会导致此问题。用withRouter HOC包装“建议”组件。此外,请确保将Search组件呈现为子组件或Router组件

import React, { Component, Fragment } from "react";
import { Link, withRouter } from "react-router-dom";
import styled from "styled-components";
import axios from "axios";

const SuggestionsResult = styled.ul`
  text-decoration: none;
  list-style: none;
  text-align: left;
  display: flex;
  flex-direction: column;
  width: 100%;
`;

const ResultItem = styled.li`
  border-bottom: 0.0625rem solid hsla(0, 0%, 100%, 0.12);
  padding: 10px 0 10px;
  padding-left: 2px;
  font-size: 1em;
  cursor: pointer;
  &:hover {
    background: hsla(0, 0%, 100%, 0.12);
  }
`;

export default class Search extends Component {
  state = {
    query: "",
    results: [],
    showSuggestions: false
  };

  handleInputChange = () => {
    this.setState(
      {
        query: this.search.value
      },
      () => {
        if (this.state.query && this.state.query.length > 1) {
          if (this.state.query.length % 2 === 0) {
            axios
              .get(
                `https://api.themoviedb.org/3/search/movie?api_key=${apiKey}&language=en-US&query=${
                  this.state.query
                }&page=1&include_adult=false`
              )
              .then(({ data }) => {
                this.setState({
                  results: data.results,
                  showSuggestions: !this.state.showSuggestions
                });
              });
          }
        } else if (!this.state.query) {
        }
      }
    );
  };



  handleSuggestionClick = e => {
    this.setState({ showSuggestions: false });
  };

  render() {
    return (
      <Fragment>
        <input
          placeholder="Search for a movie..."
          ref={input => (this.search = input)}
          onChange={this.handleInputChange}
        />
        {this.state.showSuggestions && (
          <Suggestions
            results={this.state.results}
            handleSuggestionClick={this.handleSuggestionClick}
          />
        )}
      </Fragment>
    );
  }
}

const Suggestions = withRouter(({ results, handleSuggestionClick }) => {
  const options = results.map(r => (
    <ResultItem key={r.id}>
      <Link onClick={handleSuggestionClick} to={`/${r.id}`}>
        {r.title}
      </Link>
    </ResultItem>
  ));
  return <SuggestionsResult>{options}</SuggestionsResult>;
});