Передача значения страницы из Pagination.jsx в App.jsx

Пока я пытаюсь войти в React, я начал проект и застрял. Может быть, кто-то может помочь мне найти проблему. Ниже я объясню, что должно делать приложение.

Пользователь вводит запрос в поле ввода внутри SearchBar.jsx. Компонент SearchBar передает запрос в App.jsx и запускает функцию fetchPhotos, которая запускает запрос API.

Чтобы разобраться с разбиением на страницы, App.jsx импортирует Разбиение на страницы.jsx, который вычисляет количество изображений в ответе и отображает кнопки разбивки на страницы.

Выше работает.

Но теперь, если вы нажмете кнопку разбивки на страницы, значение страница из компонента разбивки на страницы должно быть передано в App.jsx и, следовательно, в функцию fetchPhotos (запускает запрос API).

Я предполагаю, что проблема в том, что значение страница никогда не попадает в App.jsx, поэтому в запросе API отсутствует значение page.

Я потратил часы, но не смог найти способ исправить это из-за недостатка знаний. Не могли бы вы указать мне правильное направление и показать мне, что не так с кодом?

App.jsx

import React, { Component } from "react";
import axios from "axios";
import Pagination from "../Pagination";
import SearchBar from "../SearchBar";
import ListItem from "../ListItem";
import "./app.scss";

class App extends Component {
  state = {
    photos: [],
    totalPhotos: 0,
    perPage: 30,
    currentPage: 1,
    query: null
  };

  componentDidMount() {
    this.fetchPhotos("gorilla", this.state.currentPage);
  }

  fetchPhotos = (inputValue, page) => {
    const baseUrl = "https://api.unsplash.com/search/photos";

    const options = {
      headers: {
        Authorization: `Client-ID ${process.env.REACT_APP_UNSPLASH_API_KEY}`
      },
      params: {
        query: inputValue,
        page: this.state.page,
        per_page: this.state.perPage
      }
    };

    axios
      .get(baseUrl, options)
      .then(response => {
        this.setState({
          photos: response.data.results,
          totalPhotos: parseInt(response.headers["x-total"]),
          currentPage: page,
          query: inputValue
        });

      })
      .catch(() => {
        console.info("Error");
      });
  };

  render() {
    return (
      <div className = "app">
        <SearchBar onSubmit = {this.fetchPhotos} />
        <Pagination
          current = {this.state.currentPage}
          total = {this.state.totalPhotos}
          perPage = {this.state.perPage}
          query = {this.state.query}
          onPageChanged = {query => this.fetchPhotos(this.state.query)}
        />
        <List data = {this.state.photos} />
      </div>
    );
  }
}

const List = ({ data }) => {
  var items = data.map(photo => <ListItem key = {photo.id} photo = {photo} />);
  return <div className = "grid">{items}</div>;
};

export default App;

SearchBar.jsx

import React, { Component } from "react";

class SearchBar extends Component {
  state = {
    inputValue: ""
  };

  handleFormSubmit = e => {
    e.preventDefault();
    this.props.onSubmit(this.state.inputValue);
  };

  render() {
    return (
      <div className = "header">
        <h1>Search for images on Unsplash</h1>
        <form onSubmit = {this.handleFormSubmit} className = "ui form">
          <input
            type = "text"
            placeholder = "Type here to search for images"
            value = {this.state.inputValue}
            onChange = {e => this.setState({ inputValue: e.target.value })}
          />
        </form>
      </div>
    );
  }
}

экспортировать SearchBar по умолчанию;

Разбиение на страницы.jsx

import React, { Component } from "react";

class Pagination extends Component {
  pages() {
    var pages = [];
    for (var i = this.rangeStart(); i <= this.rangeEnd(); i++) {
      pages.push(i);
    }
    return pages;
  }

  rangeStart() {
    var start = this.props.current - this.props.pageRange;
    return start > 0 ? start : 1;
  }

  rangeEnd() {
    var end = this.props.current + this.props.pageRange;
    var totalPages = this.totalPages();
    return end < totalPages ? end : totalPages;
  }

  totalPages() {
    return Math.ceil(this.props.total / this.props.perPage);
  }

  nextPage() {
    return this.props.current + 1;
  }

  prevPage() {
    return this.props.current - 1;
  }

  hasFirst() {
    return this.rangeStart() !== 1;
  }

  hasLast() {
    return this.rangeEnd() < this.totalPages();
  }

  hasPrev() {
    return this.props.current > 1;
  }

  hasNext() {
    return this.props.current < this.totalPages();
  }

  changePage(page) {
    this.props.onPageChanged(page);
    console.info("Page inside Pagination", page);
  }

  render() {
    return (
      <div className = "pagination">
        <div className = "pagination__left">
          <span
            role = "button"
            className = {!this.hasPrev() ? "hidden" : ""}
            onClick = {e => this.changePage(this.prevPage())}
          >
            Prev
          </span>
        </div>

        <div className = "pagination__mid">
          <ul>
            <li className = {!this.hasFirst() ? "hidden" : ""}>
              <span role = "button" onClick = {e => this.changePage(1)}>
                1
              </span>
            </li>
            <li className = {!this.hasFirst() ? "hidden" : ""}>...</li>
            {this.pages().map((page, index) => {
              return (
                <li key = {index}>
                  <span
                    role = "button"
                    onClick = {e => this.changePage(page)}
                    className = {this.props.current === page ? "current" : ""}
                  >
                    {page}
                  </span>
                </li>
              );
            })}
            <li className = {!this.hasLast() ? "hidden" : ""}>...</li>
            <li className = {!this.hasLast() ? "hidden" : ""}>
              <span
                role = "button"
                onClick = {e => this.changePage(this.totalPages())}
              >
                {this.totalPages()}
              </span>
            </li>
          </ul>
        </div>

        <div className = "pagination__right">
          <span
            className = {!this.hasNext() ? "hidden" : ""}
            onClick = {e => this.changePage(this.nextPage())}
          >
            Next
          </span>
        </div>
      </div>
    );
  }
}

Pagination.defaultProps = {
  pageRange: 2
};

export default Pagination;
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
68
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, что ваша ошибка связана с `onChange', потому что вы даете запрос текущего состояния для получения вместо нового запроса:

onPageChanged = {query => this.fetchPhotos(this.state.query)}

Вы должны заменить его на новый запрос, например:

onPageChanged = {query => this.fetchPhotos(query)}

РЕДАКТИРОВАТЬ 1:

Вы можете увидеть, как это работает на https://codesandbox.io/s/9ymjj8ko9p?fontsize=14.

Изменения, как я уже сказал, в App.jsx:

  1. params исправлена ​​передача страницы из параметров функции, а не из
  2. исправить свойство onPageChange для нумерации страниц, например:

    onPageChanged = {page => this.fetchPhotos(this.state.query, page)}
    

ВАУ! Большое спасибо @Cespejo.

user1941537 27.02.2019 16:05

Другие вопросы по теме