Не работает map
This commit is contained in:
@@ -2,9 +2,8 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite + React</title>
|
||||
<title>УлЧУ</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
42
src/App.css
42
src/App.css
@@ -1,42 +0,0 @@
|
||||
#root {
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 6em;
|
||||
padding: 1.5em;
|
||||
will-change: filter;
|
||||
transition: filter 300ms;
|
||||
}
|
||||
.logo:hover {
|
||||
filter: drop-shadow(0 0 2em #646cffaa);
|
||||
}
|
||||
.logo.react:hover {
|
||||
filter: drop-shadow(0 0 2em #61dafbaa);
|
||||
}
|
||||
|
||||
@keyframes logo-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
a:nth-of-type(2) .logo {
|
||||
animation: logo-spin infinite 20s linear;
|
||||
}
|
||||
}
|
||||
|
||||
.card {
|
||||
padding: 2em;
|
||||
}
|
||||
|
||||
.read-the-docs {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
31
src/App.jsx
31
src/App.jsx
@@ -1,34 +1,11 @@
|
||||
import { useState } from 'react'
|
||||
import reactLogo from './assets/react.svg'
|
||||
import viteLogo from '/vite.svg'
|
||||
import News from "./components/News/News"
|
||||
import './App.css'
|
||||
|
||||
function App() {
|
||||
const [count, setCount] = useState(0)
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<a href="https://vite.dev" target="_blank">
|
||||
<img src={viteLogo} className="logo" alt="Vite logo" />
|
||||
</a>
|
||||
<a href="https://react.dev" target="_blank">
|
||||
<img src={reactLogo} className="logo react" alt="React logo" />
|
||||
</a>
|
||||
</div>
|
||||
<h1>Vite + React</h1>
|
||||
<div className="card">
|
||||
<button onClick={() => setCount((count) => count + 1)}>
|
||||
count is {count}
|
||||
</button>
|
||||
<p>
|
||||
Edit <code>src/App.jsx</code> and save to test HMR
|
||||
</p>
|
||||
</div>
|
||||
<p className="read-the-docs">
|
||||
Click on the Vite and React logos to learn more
|
||||
</p>
|
||||
</>
|
||||
<div className="m-2">
|
||||
<News />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
38
src/components/News/Hooks/NewsHook.jsx
Normal file
38
src/components/News/Hooks/NewsHook.jsx
Normal file
@@ -0,0 +1,38 @@
|
||||
import { useState } from "react"
|
||||
|
||||
export const useNews = () => {
|
||||
const [News, setNews] = useState([])
|
||||
|
||||
const addNews = (id, name, teg, description) => {
|
||||
const newNews = {}
|
||||
newNews.id = id
|
||||
newNews.name = name
|
||||
newNews.teg = teg
|
||||
newNews.description = description
|
||||
setNews([...News, newNews])
|
||||
}
|
||||
|
||||
const editNews = (id, name, teg, description) => {
|
||||
setNews(
|
||||
News.map((news) => {
|
||||
if (news.id === id) {
|
||||
return { news, id, name, teg, description }
|
||||
} else {
|
||||
return news
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
const removeNews = (id) => {
|
||||
setNews(News.filter((news) => news.id !== id))
|
||||
}
|
||||
|
||||
const sortNews = () => {
|
||||
const newNews = [...News]
|
||||
newNews.reverse()
|
||||
setNews(newNews)
|
||||
}
|
||||
|
||||
return { News, addNews, editNews, removeNews, sortNews }
|
||||
}
|
||||
9
src/components/News/News.jsx
Normal file
9
src/components/News/News.jsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import NewsInfo from "./NewsItem/NewsInfo"
|
||||
|
||||
export default function News({className = null}) {
|
||||
return (
|
||||
<div className = {className}>
|
||||
<NewsInfo />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
0
src/components/News/News.module.css
Normal file
0
src/components/News/News.module.css
Normal file
75
src/components/News/NewsItem/NewsInfo.jsx
Normal file
75
src/components/News/NewsItem/NewsInfo.jsx
Normal file
@@ -0,0 +1,75 @@
|
||||
import { useState } from "react"
|
||||
import NewsItem from "./NewsItem"
|
||||
import { useNews } from "../Hooks/NewsHook"
|
||||
|
||||
let key = 1
|
||||
|
||||
export default function NewsInfo() {
|
||||
const [inputs, setInputs] = useState({ id: "", name: "", teg: "", description: "" })
|
||||
const { news, addNews, editNews, removeNews, sortNews } = useNews()
|
||||
|
||||
const handleClear = () => {
|
||||
setInputs({ id: "", name: "", teg: "", description: "" })
|
||||
}
|
||||
|
||||
const handleSubmit = (event) => {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
|
||||
if (!inputs.id) {
|
||||
addNews(key++, inputs.name, inputs.teg, inputs.description)
|
||||
} else {
|
||||
editNews(inputs.id, inputs.name, inputs.teg, inputs.description)
|
||||
}
|
||||
|
||||
handleClear()
|
||||
};
|
||||
|
||||
const handleEdit = (id) => {
|
||||
const data = news.find((news) => news.id === id)
|
||||
if (!data) {
|
||||
return
|
||||
}
|
||||
setInputs({ ...inputs, ...data })
|
||||
};
|
||||
|
||||
const handleRemove = (id) => {
|
||||
removeNews(id)
|
||||
handleClear()
|
||||
};
|
||||
|
||||
const handleChange = (event) => {
|
||||
setInputs({ ...inputs, [event.target.name]: event.target.value })
|
||||
};
|
||||
|
||||
const newsItems = news.map((item) => {
|
||||
return <NewsItem key={item.id} news={item} onEdit={handleEdit} onDelete={handleRemove} />
|
||||
})
|
||||
|
||||
return (
|
||||
<div className="card my-2 p-2">
|
||||
<h5 className="my-2">Новости</h5>
|
||||
<form className="my-2 p-2" onSubmit={handleSubmit}>
|
||||
<input name="id" type="hidden" value={inputs.id} />
|
||||
<p>Название</p>
|
||||
<input name="name" type="text" value={inputs.name} onChange={handleChange} required />
|
||||
<p>Тег</p>
|
||||
<input name="teg" type="text" value={inputs.teg} onChange={handleChange} required />
|
||||
<p>Описание</p>
|
||||
<input name="description" type="text" value={inputs.description} onChange={handleChange} required />
|
||||
<div className="my-2">
|
||||
<button type="submit" className="mx-2">
|
||||
Сохранить
|
||||
</button>
|
||||
<button type="button" className="mx-2" onClick={handleClear}>
|
||||
Очистить
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<button className="d-block my-2" onClick={() => sortNews()}>
|
||||
Сортировать
|
||||
</button>
|
||||
{newsItems}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
13
src/components/News/NewsItem/NewsItem.jsx
Normal file
13
src/components/News/NewsItem/NewsItem.jsx
Normal file
@@ -0,0 +1,13 @@
|
||||
export default function NewsItem({news, onEdit, onDelete}) {
|
||||
return (
|
||||
<div>
|
||||
<p className="m-2">Название: {news.name}</p>
|
||||
<p className="m-2">Тег: {news.teg}</p>
|
||||
<p className="m-2">{news.description}</p>
|
||||
<div className="m-2">
|
||||
<button className="m-2" onClick={() => onEdit(news.id)}>Редактировать {news.id}</button>
|
||||
<button className="m-2" onClick={() => onDelete(news.id)}>Удалить {news.id}</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user