Answer the question
In order to leave comments, you need to log in
Please rate my first Crud To-do list project on React.js + Node.js + Postgresql?
I created my first React project with server requests. Please rate it, maybe there are some flaws, something is missing or something is superfluous, or in general there is an easier way to implement it. I'll be glad to chat.
app.js
import { useState } from 'react'
import Todoform from './Components/TodoForm'
function App() {
const [todo, setTodo] = useState([])
const todoLength = (todos) => {
if (todos) {
setTodo(todos)
}
}
return (
<div className="App">
<header>
<h1>Список задач: {todo.length} </h1>
</header>
<Todoform todoLength={todoLength} />
</div>
);
}
export default App;
import { useState, useEffect } from 'react'
import ModalInput from './ModalInput';
function Todoform({ todoLength }) {
const [modalActive, setModalActive] = useState(false)
const [error, setError] = useState(null)
const [isLoaded, setIsLoaded] = useState(false)
const [todos, setTodos] = useState([])
const [userInput, setUserInput] = useState('')
const [userInputUpdate, setUserInputUpdate] = useState('')
const [todo, setTodo] = useState([])
const [isChecked, setIsChecked] = useState(false);
const handleOnChange = () => {
setIsChecked(!isChecked);
};
useEffect(() => {
getTodos()
}, [])
const getTodos = () => {
fetch('http://localhost:3001/api/todo', {
method: 'GET',
})
.then(res => res.json())
.then(
(result) => {
setIsLoaded(true);
setTodos(result);
todoLength(result)
},
(error) => {
setIsLoaded(true);
setError(error);
}
)
}
const createTodo = () => {
fetch('http://localhost:3001/api/todo', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
todo_text: userInput,
complete: false
}),
})
.then((res) => res.json())
.then(result => {
setTodos([...todos, result])
getTodos()
},
(error) => {
setIsLoaded(true)
setError(error)
}
)
}
const updateTodo = (id, todo_text, complete) => {
fetch(`http://localhost:3001/api/todo`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
todo_text: todo_text,
complete: complete,
id: id
}),
})
.then((res) => res.json())
.then(result => {
setTodos([...todos])
getTodos()
},
(error) => {
setIsLoaded(true)
setError(error)
}
)
}
const removeTodo = (id) => {
fetch(`http://localhost:3001/api/todo/${id}`, {
method: 'DELETE',
})
.then(data => {
// alert(data)
getTodos()
})
}
const handleChange = (e) => {
setUserInput(e.currentTarget.value)
}
const handleSubmit = (e) => {
e.preventDefault()
if (userInput) {
setUserInput('')
createTodo()
}
}
const handleKeyPress = (e) => {
if (e.key === 'Enter') {
handleSubmit(e)
}
}
const handleModalChange = (e) => {
setUserInputUpdate(e.currentTarget.value)
}
const handleModalSubmit = (event) => {
event.preventDefault()
if (userInputUpdate) {
setUserInputUpdate('')
updateTodo(todo[0], userInputUpdate, isChecked)
setModalActive(false)
}
}
const handleKeyPressmodal = (e) => {
if (e.key === 'Enter') {
handleModalSubmit(e)
}
}
if (error) {
return <div>Ошибка: {error.message}</div>;
} else if (!isLoaded) {
return <div>Загрузка...</div>;
} else if (todos) {
return (
<div>
<form onSubmit={handleSubmit}>
<input
className='input'
value={userInput}
type="text"
onChange={handleChange}
onKeyDown={handleKeyPress}
placeholder="Введите текст"
/>
<button className="item-save">Сохранить</button>
</form>
{todos.map((todo) => {
return (<div className="todos" >
<div key={todo.id} className="item-todo" >
<div className={todo.complete ? "item-text strike" : "item-text"} >
{todo.todo_text} {todo.complete}
</div>
<div className='todo-checkbox'>
<input className='checkbox' type="checkbox" checked={todo.complete ? true : false} onChange={() => { updateTodo(todo.id, todo.todo_text, !todo.complete); setIsChecked(!todo.complete) }} />
</div>
</div>
<button className="item-update" onClick={() => { setModalActive(true); setTodo([todo.id, todo.todo_text, todo.complete]); setUserInputUpdate(todo.todo_text); setIsChecked(todo.complete) }}>
Изменить
</button>
<button className="item-delete" onClick={() => removeTodo(todo.id)}>
X
</button>
</div>)
})}
<ModalInput active={modalActive} setActive={setModalActive}>
<form onSubmit={handleModalSubmit}>
<input
className='input'
value={userInputUpdate}
type="text"
onChange={handleModalChange}
onKeyDown={handleKeyPressmodal}
placeholder="Введите текст"
/>
<input className='checkbox' type="checkbox" checked={isChecked ? true : false} onChange={handleOnChange} />
<button className="item-save">Сохранить</button>
</form>
</ModalInput>
</div>
)
}
}
export default Todoform
const ModalInput = ({ active, setActive, children }) => {
return (
<div className={active ? "modal active" : "modal"} onClick={() => setActive(false)}>
<div className={active ? "modal__content active" : "modal__content"} onClick={e => e.stopPropagation()}>
{children}
</div>
</div>
)
}
export default ModalInput
Answer the question
In order to leave comments, you need to log in
On questions:
1 There is not much difference, only for your IDE - it will make the hints more correctly in the jsx file
2 The first warning that you use key={todo.id} is a bit wrong - you need to move it to the parent div
<div className="todos" вот сюда>
<div key={todo.id} className="item-todo" >
useEffect(() => {
getTodos()
}, [вот тут])
useEffect(() => {
getTodos()
// eslint-disable-next-line
}, [])
1) asynchronous requests should be wrapped in useMemo or useCallback
2)checked={isChecked ? true : false} abbreviate to checked={isChecked}
3) the list has a key in the wrong place - here the key
4) it is better to use sequelize for queries to the database
5) all information from db.js must be stored in .env
6) it is easier to use package cors
7) to the project, you need to describe the readme with info on how to run it <div className="todos" >
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question