[英]React, problem with my Todo list app, my search engine only finds notes on the page I'm on
Hello I am making an application to practice React, my notes app has a pagination which works perfectly, the problem is in the search engine, which only looks for notes from the page I'm on, for example, if I'm on page 2 and I look for a note on page 2, it shows it, however if the note is on a different page, it doesn't show it, it doesn't find it.您好,我正在制作一个练习 React 的应用程序,我的笔记应用程序有一个完美运行的分页,问题出在搜索引擎中,它只查找我所在页面的笔记,例如,如果我在页面上2,我在第 2 页上查找注释,它显示它,但是如果注释在不同的页面上,它不会显示它,它找不到它。
I know where the problem is but I'm not sure how to solve it, I'm a bit new to React and I was asking for your help.我知道问题出在哪里,但我不知道如何解决它,我对 React 有点陌生,我正在寻求你的帮助。
I was able to do my pagination with the package react-paginate
here is the documentation https://www.npmjs.com/package/react-paginate我能够使用包
react-paginate
这里是文档https://www.npmjs.com/package/react-paginate
My code:我的代码:
Component App.js
组件
App.js
import { useState, useEffect } from "react";
import { nanoid } from 'nanoid';
import './App.css';
import Search from "./components/Search";
import Header from "./components/Header";
import Pagination from "./components/Pagination";
const App = () => {
const [notes, setNotes] = useState([]);
const [searchText, setSearchText] = useState('');
const [darkMode, setDarkMode] = useState(false);
const [showNote, setShowNote] = useState(true); //eslint-disable-line
useEffect(() => {
const saveNotes = JSON.parse(localStorage.getItem('notes-data'));
if (saveNotes){
setNotes(saveNotes);
}
}, []);
useEffect(() => {
localStorage.setItem('notes-data', JSON.stringify(notes))
},[notes])
const addNote = (inputText, text) => {
const date = new Date();
const newNote = {
id: nanoid(),
title: inputText,
text: text,
date: date.toLocaleString()
}
const newNotes = [newNote, ...notes];
setNotes(newNotes)
}
const deleteNote = (id) => {
var response = window.confirm("Are you sure?");
if (response){
const notesUpdated = notes.filter((note) => note.id !== id)
setNotes(notesUpdated);
}
}
return (
<div className={darkMode ? 'dark-mode' : ''}>
<div className="container">
<Header
handleToggleTheme={setDarkMode}
/>
<Search
handleSearchNote={setSearchText}
setShowNote={setShowNote}
/>
<Pagination
data={notes}
handleAddNote={addNote}
handleDeleteNote={deleteNote}
searchText={searchText}
/>
</div>
</div>
)
}
export default App;
Component Pagination.js
组件
Pagination.js
import React, { useEffect, useState } from 'react'
import ReactPaginate from 'react-paginate';
import '../styles/Pagination.css';
import NoteList from './NoteList';
import { MdSkipPrevious, MdSkipNext } from 'react-icons/md';
const Pagination = (props) => {
const { data, searchText, handleAddNote, handleDeleteNote } = props;
// We start with an empty list of items.
const [currentItems, setCurrentItems] = useState([]);
const [pageCount, setPageCount] = useState(0);
// Here we use item offsets; we could also use page offsets
// following the API or data you're working with.
const [itemOffset, setItemOffset] = useState(0);
const itemsPerPage = 9;
useEffect(() => {
// Fetch items from another resources.
const endOffset = itemOffset + itemsPerPage;
console.log(`Loading items from ${itemOffset} to ${endOffset}`);
setCurrentItems(data.slice(itemOffset, endOffset));
setPageCount(Math.ceil(data.length / itemsPerPage));
}, [itemOffset, itemsPerPage, data]);
// Invoke when user click to request another page.
const handlePageClick = (event) => {
const newOffset = (event.selected * itemsPerPage) % data.length;
console.log(
`User requested page number ${event.selected}, which is offset ${newOffset}`
);
setItemOffset(newOffset);
};
return (
<>
<NoteList
notes={currentItems.filter((noteText) =>
noteText.title.toLowerCase().includes(searchText)
)}
handleAddNote={handleAddNote}
handleDeleteNote={handleDeleteNote}
/>
<div className="pagination-wrapper">
<ReactPaginate
breakLabel="..."
nextLabel={<MdSkipNext
className='icons'
/>}
onPageChange={handlePageClick}
pageRangeDisplayed={3}
pageCount={pageCount}
previousLabel={<MdSkipPrevious
className='icons'
/>}
renderOnZeroPageCount={null}
containerClassName="pagination"
pageLinkClassName="page-num"
previousLinkClassName="page-num"
nextLinkClassName="page-num"
activeLinkClassName="activee boxx"
/>
</div>
</>
);
}
export default Pagination;
Component NoteList.js
组件
NoteList.js
import React from 'react'
import Note from './Note'
import '../styles/NoteList.css'
import AddNote from './AddNote'
const NoteList = ({ notes, handleAddNote, handleDeleteNote }) => {
return (
<>
<div className="add-notes-wrapper">
<AddNote
handleAddNote={handleAddNote}
/>
</div>
<div className='notes-list'>
{notes.map((note =>
<Note
key={note.id}
id={note.id}
title={note.title}
text={note.text}
date={note.date}
handleDeleteNote={handleDeleteNote}
/>
))}
</div>
</>
)
}
export default NoteList;
Component Search.js
组件
Search.js
//import React, { useState } from 'react'
import {MdSearch, MdAdd} from 'react-icons/md'
import '../styles/Search.css'
const Search = ({ handleSearchNote, setShowNote }) => {
const handleShowAddNote = () => {
if (setShowNote){
let addNote = document.querySelector('.new');
addNote.classList.add('wobble-horizontal-top')
addNote.style.display='flex';
document.querySelector('.notes-list').style.display='none';
document.querySelector('.pagination').style.display='none';
}
}
return (
<div className='search'>
<div className="input-wrapper">
<MdSearch
className='icon search-icon'
/>
<input
type="text"
placeholder='What note are you looking for?'
onChange={(event) => handleSearchNote(event.target.value) }
/>
</div>
<div className="btn-wrapper-search">
<button
className='btn-addNote'
onClick={handleShowAddNote}>
Nueva Nota
</button>
<MdAdd
className='icon add-icon'
/>
</div>
</div>
)
}
export default Search
The problem is in the component Pagination.js
because I'm filtering the notes on each page with the currentItems
variable, if I did it with the data
variable it would work, but then it would show all the notes, and I don't want that, I currently want to show 9 notes per page.问题出在组件
Pagination.js
中,因为我正在使用currentItems
变量过滤每个页面上的注释,如果我使用data
变量进行过滤,它会起作用,但它会显示所有注释,而我没有想要那个,我目前想每页显示 9 个注释。
greetings and thanks in advance.提前问候和感谢。
Edit:编辑:
@Newbie I'm doing what you said, but I don't know if you mean this, in my Pagination.js
component I did: @Newbie我正在做你所说的,但我不知道你是否是这个意思,在我的
Pagination.js
组件中我做了:
useEffect(() => {
const filterNotes=data.filter((noteText) =>
noteText.title.toLowerCase().includes(searchText)
)
setItemOffset(0);
}, [data, searchText])
It doesn't work, do I have to pass a prop to my components additionally?它不起作用,我是否必须另外向我的组件传递一个道具? greetings.
问候。
As I suggested to you, search all the notes with searchText
in your App.js and pass the results into the Pagination component and it will solve your problem.正如我向您建议的那样,在您的 App.js 中使用
searchText
搜索所有注释,并将结果传递给 Pagination 组件,它将解决您的问题。
Codesandbox: https://codesandbox.io/s/youthful-thompson-xugs0c Codesandbox: https ://codesandbox.io/s/youthful-thompson-xugs0c
Edit编辑
All changes are as per what we talked about in the email.所有更改都按照我们在电子邮件中讨论的内容进行。
Codesandbox: https://codesandbox.io/s/green-fast-3k76wx Codesandbox: https ://codesandbox.io/s/green-fast-3k76wx
Search and pagination do not play well together, one of the common solutions is to jump to page 1 each time the filter term changes.搜索和分页并不能很好地配合使用,一种常见的解决方案是每次过滤词发生变化时跳转到第 1 页。
So use an useEffect
on searchText
to filter data
and reset itemOffset
to 0, then redo pagination as if the data changed.因此在
useEffect
上使用searchText
过滤data
并将itemOffset
重置为 0,然后像数据更改一样重做分页。
The user will jump to page 1 at each keystroke of the search, then he can navigate pages (if there are more than one).用户将在搜索的每一次击键时跳转到第 1 页,然后他可以浏览页面(如果有多个页面)。 This will lead to a less confusing UX.
这将导致用户体验不那么混乱。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.