Я новичок, чтобы реагировать. Мои кнопки ввода поиска и разбивки на страницы ничего не вызывают, и в консоли ничего не появляется, что не так с моим кодом?
Я попытался поместить все функции в 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.
Есть идеи ?
Проблема в том, что в классе List
вы пытаетесь взять updateSearch
и handleClick
из data
(которое, в свою очередь, получается из this.props
). Но updateSearch
и handleClick
никогда не помещаются внутрь data
. Если вы зарегистрируете любой из этих методов в консоли, вы увидите, что они не определены.
Чтобы это исправить, нужно передать updateSearch
и handleClick
с App
на List
. Вы можете сделать это, либо включив методы внутри свойства data
, либо передав их напрямую как собственные свойства (что я бы рекомендовал).
Например, вы можете изменить метод 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
ниже.