повторяющиеся элементы из поиска - PullRequest
0 голосов
/ 03 августа 2020

Я создаю приложение для поиска изображений, в котором пользователь может искать изображения. В моем коде есть проблема. Предположим, я ищу цветы и нажимаю Enter, тогда цветы будут показаны, но если я снова нажму Enter, то те же предыдущие цветы будут добавлены к уже существующим цветам. Я хочу, чтобы, если я снова нажму Enter с тем же термином, те же цветы не будут добавлены. Мне пришлось использовать оператор распространения из-за кнопки load more, потому что это загружало бы больше фотографий искомого элемента. Как решить проблему дублирования изображений? Я совсем новичок и застрял в этой проблеме с полудня, любая помощь будет принята с благодарностью.

import React, { Component } from "react";
import Pagination from "./Pagination";
import List from "./List";
import "./styles.css";
import axios from "axios";

const LOAD_STATE = {
  SUCCESS: "SUCCESS",
  ERROR: "ERROR",
  LOADING: "LOADING"
};

export default class App extends Component {
  constructor() {
    super();
    this.handleChange = this.handleChange.bind(this);
    this.fetchPhotos = this.fetchPhotos.bind(this);

    this.state = {
      photos: [],
      totalPhotos: 0,
      perPage: 9,
      currentPage: 1,
      loadState: LOAD_STATE.LOADING,
      search: "",
      prevSearch: ""
    };
  }

  handleChange(e) {
    this.setState({ search: e.target.value });
  }

  componentDidMount() {
    this.fetchPhotos(this.state.currentPage);
  }

  fetchPhotos(page = 1) {
    // e.preventDefault()
    var self = this;
    const { search, perPage, prevSearch } = this.state;
    const url1 = `https://api.unsplash.com/photos?page=${page}&client_id=${appId}`;
    const url2 =
      `https://api.unsplash.com/search/photos?page=${page}&query=` +
      search +
      "&client_id=" +
      appId;
    const url = search ? url2 : url1;

    const isSameSearch = prevSearch === search;
    if (search) {
      const options = {
        params: {
          page: page,
          per_page: perPage,
          order_by: "popularity"
        }
      };

      this.setState({ loadState: LOAD_STATE.LOADING });
      axios
        .get(url, options)
        .then(response => {
          if (!isSameSearch) {
            this.setState({
              photos: [...response.data.results],
              totalPhotos: parseInt(response.headers["x-total"]),
              currentPage: page,
              loadState: LOAD_STATE.SUCCESS,
              prevSearch: search
            });
          } else {
            this.setState({
              photos: [...this.state.photos, ...response.data.results],
              totalPhotos: parseInt(response.headers["x-total"]),
              currentPage: page,
              loadState: LOAD_STATE.SUCCESS
            });
          }
        })
        .catch(() => {
          this.setState({ loadState: LOAD_STATE.ERROR });
        });
    } else {
      const options = {
        params: {
          client_id: appId,
          page: page,
          per_page: perPage,
          order_by: "popularity"
        }
      };

      this.setState({ loadState: LOAD_STATE.LOADING });
      axios
        .get(url, options)
        .then(response => {
          self.setState({
            photos: [...this.state.photos, ...response.data],
            totalPhotos: parseInt(response.headers["x-total"]),
            currentPage: page,
            loadState: LOAD_STATE.SUCCESS
          });
        })
        .catch(() => {
          this.setState({ loadState: LOAD_STATE.ERROR });
        });
    }
  }

  render() {
    return (
      <div className="app">
        <input
          onChange={this.handleChange}
          type="text"
          name="search"
          placeholder="Enter query"
        />
        <button
          type="submit"
          onClick={() => this.fetchPhotos(1)}
          className="button"
        >
          Submit
        </button>

        <List data={this.state.photos} />
        {this.state.loadState === LOAD_STATE.LOADING && (
          <div className="loader" />
        )}
        <Pagination
          current={this.state.currentPage}
          total={this.state.totalPhotos}
          perPage={this.state.perPage}
          onPageChanged={this.fetchPhotos.bind(this)}
        />
      </div>
    );
  }
}

Ответы [ 2 ]

1 голос
/ 03 августа 2020

Проблема заключается в том, что когда вы нажимаете Submit несколько раз для flower, он переходит ко второй ветви условного оператора, который photos: [...this.state.photos, ...response.data.results], что приводит вас к неожиданному поведению

if (!isSameSearch) {
  this.setState({
    photos: [...response.data.results],
    totalPhotos: parseInt(response.headers["x-total"]),
    currentPage: page,
    loadState: LOAD_STATE.SUCCESS,
    prevSearch: search,
  })
} else {
  this.setState({
    photos: [...this.state.photos, ...response.data.results],
    totalPhotos: parseInt(response.headers["x-total"]),
    currentPage: page,
    loadState: LOAD_STATE.SUCCESS,
  })
}

Решение может быть простым, в вашем logi c, каждый раз, когда вы нажимаете Submit, вы запрашиваете с page из 1, это главный ключ, а не предыдущий поиск, поэтому всякий раз, когда страница равна 1, просто получите результат с нуля

if (page === 1) {
  this.setState({
    photos: [...response.data.results],
    totalPhotos: parseInt(response.headers["x-total"]),
    currentPage: page,
    loadState: LOAD_STATE.SUCCESS,
    prevSearch: search,
  })
} else {
  this.setState({
    photos: [...this.state.photos, ...response.data.results],
    totalPhotos: parseInt(response.headers["x-total"]),
    currentPage: page,
    loadState: LOAD_STATE.SUCCESS,
  })
}

Ниже находится окно с раздвоенными кодами

Редактировать crazy-germain-xk8ud

0 голосов
/ 03 августа 2020

Эта строка не выполняет то, что вы думаете:

const { search, perPage, prevSearch } = this.state;

this.state имеет 7 элементов, поэтому вы неправильно определяете эти переменные:

this.state = {
  photos: [],
  totalPhotos: 0,
  perPage: 9,
  currentPage: 1,
  loadState: LOAD_STATE.LOADING,
  search: "",
  prevSearch: "",
}

Попробуйте это :

var search = this.state.search;
var prevSearch = this.state.prevSearch;
var perPage = this.state.perPage;

(и они не константы, это переменные)

Другие проблемы:

У вас url как константа, и вы никогда не обновляете его параметр page. Вы всегда будете пинговать как page=1.

Даже если я исправлю это и обновлю параметр page=, URL-адрес не будет разбиваться на страницы, как вы ожидали. Он возвращает 9 изображений, затем 18, затем 27

У вас еще много работы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...