Не работает map
This commit is contained in:
@@ -2,9 +2,8 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<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" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Vite + React</title>
|
<title>УлЧУ</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<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;
|
|
||||||
}
|
|
||||||
|
|||||||
33
src/App.jsx
33
src/App.jsx
@@ -1,35 +1,12 @@
|
|||||||
import { useState } from 'react'
|
import News from "./components/News/News"
|
||||||
import reactLogo from './assets/react.svg'
|
|
||||||
import viteLogo from '/vite.svg'
|
|
||||||
import './App.css'
|
import './App.css'
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [count, setCount] = useState(0)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className="m-2">
|
||||||
<div>
|
<News />
|
||||||
<a href="https://vite.dev" target="_blank">
|
</div>
|
||||||
<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>
|
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default App
|
export default App
|
||||||
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