#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
ниже.