У меня большие проблемы с фильтрацией объекта массива объектов по его идентификатору в React. Позволь мне объяснить:
Приложение представляет собой приложение для заметок, в котором хранится каждая созданная вами заметка с ее заголовком, текстом (имя) и датой создания. Ключ - это идентификатор.
Теперь я пытаюсь создать модальное всплывающее окно каждый раз, когда я нажимаю на заметку, что мне удалось сделать хорошо, за исключением одного: когда появляется модальное окно, оно показывает не только выбранную заметку, но и весь список заметок. Я пытался с помощью разных методов массива отфильтровать нужную мне заметку, но безуспешно.
Это файл App.js:
import React, { useState } from 'react';
import './App.css';
import Form from './components/Form';
import List from './components/List';
import { v4 as uuidv4 } from 'uuid';
import Modal from 'react-modal';
import ModalList from './components/ModalList';
Modal.setAppElement('#root');
function App() {
/*HOOKS */
const [list, setList] = useState([]);
const [modalList, setModalList] = useState([]);
//for modal:
let subtitle;
const [modalIsOpen, setIsOpen] = React.useState(false);
/*FUNCTIONS */
//add new notes
function handleAdd(title, name) {
if (name) {
const newList = list.concat({ title: title, name: name, id: uuidv4(), date: getCurrentDate() });
setList(newList);
console.info(newList);
const newModalList = list.concat({ title: title, name: name, id: uuidv4(), date: getCurrentDate() });
setModalList(newModalList);
}
else { alert("You should complete the notes field") }
}
//get the date for adding the note
function getCurrentDate() {
let newDate = new Date()
let date = newDate.getDate();
let month = newDate.getMonth() + 1;
let year = newDate.getFullYear();
let hours = newDate.getHours();
let minutes = newDate.getMinutes();
return `${month < 10 ? `0${month}` : `${month}`}/${date}/${year}, ${hours}:${minutes < 10 ? `0${minutes}` : `${minutes}`} hs.`
}
//deleting a note
function del(x) {
if (window.confirm("Do you really want to delete this item? The action is permanent.")) {
const newList = list.filter((item) => item.id !== x);
setList(newList);
}
}
//opening a modal
function openModal() {
setIsOpen(true);
}
//after opening a modal
function afterOpenModal() {
// references are now sync'd and can be accessed.
subtitle.style.color = '#f00';
}
//closing a modal
function closeModal() {
setIsOpen(false);
}
/*APP */
return (
<>
<div>
{/* MODAL */}
<Modal
isOpen = {modalIsOpen}
onAfterOpen = {afterOpenModal}
onRequestClose = {closeModal}
style = {customStyles}
contentLabel = "Example Modal"
>
{modalList.map((item) => { return <ModalList key = {item.id} item = {item} quit = {closeModal} /> })}
</Modal>
</div>
{/* FORM */}
<div className='App'>
<Form handleNew = {handleAdd} />
</div>
{/* NOTES LIST */}
<div className='notes-list'>
{list.map((item) => { return <List key = {item.id} item = {item} quit = {del} addModal = {openModal} /> })}
</div>
</>
);
}
export default App;
А это файл ModalList.jsx:
const ModalList = (props) => {
const { item, quit} = props;
/*LIST */
return (
<li ><button className='delete' onClick = {()=>quit(item.id)}>x</button><p className='note-title'>{item.title}</p><p>{item.date}</p><p className='note-name'>{item.name}</p> </li>
);
}
export default ModalList;
Я знаю, что мне нужно каким-то образом отфильтровать объект по его идентификатору, чтобы отображалось только то, что я щелкнул, а не все существующие элементы в списке, но я не нахожу способ.
Большое спасибо!
{list.map((item) => { return <List key = {item.id} item = {item} quit = {del} addModal = {openModal} /> })}
openModal должен передать элемент, по которому вы щелкнули, в качестве параметра и передать его обратному вызову.
Что-то вроде:
{list.map((item) => { return <List key = {item.id} item = {item} quit = {del} addModal = {() => openModal(item)} /> })}
Затем функция openModal должна передать этот параметр модальному компоненту. Для этого вы можете сохранить его в своем modalList, например, через setModalList([item])
Здесь вы используете Array.map, который делает то, что должен (перечисляет элементы), вместо этого вы должны использовать Array.filter, который вернет нужный вам ModalItem