Мой поисковый ввод и разбивка на страницы ничего не запускают в Reactjs

#reactjs

#reactjs

Вопрос:

Я довольно новичок в react. Мои кнопки ввода поиска и разбивки на страницы ничего не запускают, и в консоли ничего не отображается, что не так с моим кодом?

Я попытался вставить все функции App.js , чтобы сделать их более чистыми.

App.js

 import React, { Component } from "react";
import List from './List';

let API = 'https://swapi.co/api/people/';

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      results: [],
      search: '',
      currentPage: 1,
      todosPerPage: 3
    };
    this.handleClick = this.handleClick.bind(this);
    this.updateSearch = this.updateSearch.bind(this);
  }

  componentWillMount() {
    this.fetchData();
  }

  fetchData = async () => {
    const response = await fetch(API);
    const json = await response.json();
    this.setState({ results: json.results });
  };

  handleClick(event) {
    this.setState({
      currentPage: Number(event.target.id)
    });
  }

  updateSearch(event) {
    this.setState({ 
      search: event.target.value.substr(0, 20) 
    });
  }

  render() {
    return (
      <div>
        <List data={this.state} />
      </div>
    );
  }
}

export default App;
  

List.js

 import React, { Component } from 'react';
import Person from './Person';

class List extends Component {
    render() {
    const { data } = this.props;

    const { results, search, updateSearch, handleClick, currentPage, todosPerPage } = data;
    const indexOfLastTodo = currentPage * todosPerPage;
    const indexOfFirstTodo = indexOfLastTodo - todosPerPage;
    const currentTodos = results.slice(indexOfFirstTodo, indexOfLastTodo).filter(item => {
      return item.name.toLowerCase().indexOf(search) !== -1;
    });

    const renderTodos = currentTodos.map((item, number) => {
      return (
        <Person item={item} key={number} />
      );
    });

    const pageNumbers = [];
    for (let i = 1; i <= Math.ceil(results.length / todosPerPage); i  ) {
      pageNumbers.push(i);
    }

    const renderPageNumbers = pageNumbers.map(number => {
      return (
        <li className="page-link" key={number} id={number} onClick={handleClick} style={{cursor: "pointer"}}>{number}</li>
      );
    });

    return (
      <div className="flex-grow-1">
        <h1>Personnages de Star Wars</h1>
        <form className="mb-4">
          <div className="form-group">
            <label>Rechercher</label>
            <input 
            className="form-control" 
            type="text"
            placeholder="luke skywalker..."
            value={search}
            onChange={updateSearch}
            />
          </div>
        </form>
        <div className="row mb-5">{renderTodos}</div>
        <nav aria-label="Navigation">
          <ul id="page-number" className="pagination justify-content-center">{renderPageNumbers}</ul>
        </nav>
      </div>
    );
  }
}

export default List;
  

Значение входных данных ни на йоту не изменится, если я введу его, и если я щелкну правой кнопкой мыши по номеру страницы, консоль получит меня Uncaught DOMException: Failed to execute 'querySelectorAll' on 'Element': '#4' is not a valid selector.

Есть идеи?

Ответ №1:

Проблема в том, что в List классе вы пытаетесь взять updateSearch и handleClick из data (что, в свою очередь, происходит из this.props ). Но updateSearch и handleClick никогда не помещаются внутрь data . Если вы зарегистрируете любой из этих методов в консоли, вы увидите, что они не определены.

Чтобы исправить это, вам нужно передать updateSearch и handleClick из App в List . Вы можете сделать это, либо включив методы внутри data prop, либо передав их напрямую как их собственные реквизиты (что я бы рекомендовал).

Например, вы можете изменить render метод App , чтобы он выглядел примерно так:

 render() {
    return (
      <div>
        <List
          data={this.state}
          updateSearch={ this.updateSearch }
          handleClick={ this.handleClick }
        />
      </div>
    );
}
  

Затем в render методе List вы можете сделать это:

 const { data, updateSearch, handleClick } = this.props;
  

и удалите определения двух методов из деструктурирования data ниже.