1- Create Todo Project Setup with Bootstrap
npx create-react-app
: Sets up a new React project with a standardized structure and configuration.
cd react-todos
: Moves you into the project folder to run further commands.
npm install react@18.3.1 react-dom@18.3.1
: Ensures you’re using the specific version of React you need.
npm install web-vitals
: Adds performance monitoring to your app.
npm install axios react-router-dom bootstrap react-bootstrap
For styling and UI components
npm start
: Starts the development server so you can view and test your app.
2- Create First component TodoRowItem
function TodoRowItem(props) {
return (
<tr>
<th scope="row">{props.rowNumber}</th>
<td>{props.rowDescription}</td>
<td>{props.rowAssigned}</td>
</tr>
)
}
export default TodoRowItem
3- Create Second component TodoTable
1. Go to App.js add list named todos
function App() {
const [todos, setTodos] = useState([
{ rowNumber: 1, rowDescription: 'Feed puppy', rowAssigned: 'User One' },
{ rowNumber: 2, rowDescription: 'Water plants', rowAssigned: 'User Two' },
{ rowNumber: 3, rowDescription: 'Make dinner', rowAssigned: 'User One' },
{ rowNumber: 4, rowDescription: 'Charge phone battery', rowAssigned: 'User One' }
]
)
}
2. Create TodoTable.js
import TodoRowItem from "./TodoRowItem"
function TodoTable(props) {
return (
<table className="table table-hover">
<thead>
<tr>
<th scope='col'>#</th>
<th scope='col'>Description</th>
<th scope='col'>Assigned</th>
</tr>
</thead>
<tbody>
{props.todos.map(todo => (
<TodoRowItem
key={todo.rowNumber}
rowNumber={todo.rowNumber}
rowDescription={todo.rowDescription}
rowAssigned={todo.rowAssigned}
/>
))}
</tbody>
</table>
)
}
export default TodoTable
4- Rendering List Dynamically
import './App.css';
function App() {
return (
<div className='mt-5 container'>
<div className="card">
<div className="card-header">
Your Todo's
</div>
<div className="card-body">
<TodoTable todos={todos} /> </div>
</div>
</div>
);
}
export default App;
5- OnClick Listener
function App() {
const [todos, setTodos] = useState([
{ rowNumber: 1, rowDescription: 'Feed puppy', rowAssigned: 'User One' },
{ rowNumber: 2, rowDescription: 'Water plants', rowAssigned: 'User Two' },
{ rowNumber: 3, rowDescription: 'Make dinner', rowAssigned: 'User One' },
{ rowNumber: 4, rowDescription: 'Charge phone battery', rowAssigned: 'User One' }
]
)
const addTodo = (description, assigned) => {
let rowNumber = 0;
if (todos.length > 0) {
rowNumber = todos[todos.length - 1].rowNumber + 1;
} else {
rowNumber = 1;
}
const newTodo = {
rowNumber: rowNumber,
rowDescription: description,
rowAssigned: assigned
};
setTodos(todos => [...todos, newTodo])
}
return (
<div className='mt-5 container'>
<div className="card">
<div className="card-header">
Your Todo's
</div>
<div className="card-body">
<TodoTable todos={todos} />
<button onClick={addTodo}
className='btn btn-primary'>
Add new todo
</button>
</div>
</div>
</div>
);
}
export default App;
6- Creating Form Inputs - NewTodoForm
import React, {useState} from 'react';
function NewTodoForm(props) {
const [description, setDescription] = useState('');
const [assigned, setAssigned] = useState('');
const submitTodo = () => {
if (description !== '' && assigned !== '') {
props.addTodo(description, assigned);
setDescription('');
setAssigned('');
}
}
return (
<div className='mt-5'>
<form>
<div className='mb-3'>
<label className='form-label'>Assigned</label>
<input
type='text'
className='form-control'
required
onChange={e => setAssigned(e.target.value)}
value={assigned}
></input>
</div>
<div className='mb-3'>
<label className='form-label'>Description</label>
<textarea
className='form-control'
rows={3}
required
onChange={e => setDescription(e.target.value)}
value={description}
></textarea>
</div>
<button
type='button'
className='btn btn-primary mt-3'
onClick={submitTodo}
>
Add Todo
</button>
</form>
</div>
)
}
export default NewTodoForm
7- Adding user inputs
import React, { useState } from 'react';import './App.css';import TodoTable from './components/TodoTable';import NewTodoForm from './components/NewTodoForm';
function App() {
const [showAddTodoForm, setShowAddTodoForm] = useState(false);
const [todos, setTodos] = useState([ { rowNumber: 1, rowDescription: 'Feed puppy', rowAssigned: 'User One' }, { rowNumber: 2, rowDescription: 'Water plants', rowAssigned: 'User Two' }, { rowNumber: 3, rowDescription: 'Make dinner', rowAssigned: 'User One' }, { rowNumber: 4, rowDescription: 'Charge phone battery', rowAssigned: 'User One' } ] )
const addTodo = (description, assigned) => { let rowNumber = 0; if (todos.length > 0) { rowNumber = todos[todos.length - 1].rowNumber + 1; } else { rowNumber = 1; } const newTodo = { rowNumber: rowNumber, rowDescription: description, rowAssigned: assigned }; setTodos(todos => [...todos, newTodo]) }
return ( <div className='mt-5 container'> <div className="card"> <div className="card-header"> Your Todo's </div> <div className="card-body"> <TodoTable todos={todos} /> <button onClick={() => setShowAddTodoForm(!showAddTodoForm)} className='btn btn-primary'> {showAddTodoForm ? 'Close New Todo' : 'New Todo'} </button> {showAddTodoForm && <NewTodoForm addTodo={addTodo} /> } </div> </div> </div> );}
export default App;
8- Delete Item using React functionality
const deleteTodo = (deleteTodoRowNumber) => { let filtered = todos.filter(function (value) { return value.rowNumber !== deleteTodoRowNumber; }); setTodos(filtered); }
<div className="card-body"> <TodoTable todos={todos} deleteTodo={deleteTodo} /> <button onClick={() => setShowAddTodoForm(!showAddTodoForm)} className='btn btn-primary'>
import React, { useState } from 'react';
import './App.css';
import TodoTable from './components/TodoTable';
import NewTodoForm from './components/NewTodoForm';
function App() {
const [showAddTodoForm, setShowAddTodoForm] = useState(false);
const [todos, setTodos] = useState([
{ rowNumber: 1, rowDescription: 'Feed puppy', rowAssigned: 'User One' },
{ rowNumber: 2, rowDescription: 'Water plants', rowAssigned: 'User Two' },
{ rowNumber: 3, rowDescription: 'Make dinner', rowAssigned: 'User One' },
{ rowNumber: 4, rowDescription: 'Charge phone battery', rowAssigned: 'User One' }
]
)
const addTodo = (description, assigned) => {
let rowNumber = 0;
if (todos.length > 0) {
rowNumber = todos[todos.length - 1].rowNumber + 1;
} else {
rowNumber = 1;
}
const newTodo = {
rowNumber: rowNumber,
rowDescription: description,
rowAssigned: assigned
};
setTodos(todos => [...todos, newTodo])
}
return (
<div className='mt-5 container'>
<div className="card">
<div className="card-header">
Your Todo's
</div>
<div className="card-body">
<TodoTable todos={todos} />
<button onClick={() => setShowAddTodoForm(!showAddTodoForm)} className='btn btn-primary'>
{showAddTodoForm ? 'Close New Todo' : 'New Todo'}
</button>
{showAddTodoForm &&
<NewTodoForm addTodo={addTodo} />
}
</div>
</div>
</div>
);
}
export default App;
8- Delete Item using React functionality
const deleteTodo = (deleteTodoRowNumber) => {
let filtered = todos.filter(function (value) {
return value.rowNumber !== deleteTodoRowNumber;
});
setTodos(filtered);
}
<div className="card-body">
<TodoTable todos={todos} deleteTodo={deleteTodo} />
<button onClick={() => setShowAddTodoForm(!showAddTodoForm)} className='btn btn-primary'>
9- Conditional Rendering
<button onClick={() => setShowAddTodoForm(!showAddTodoForm)} className='btn btn-primary'> {showAddTodoForm ? 'Close New Todo' : 'New Todo'} </button> {showAddTodoForm && <NewTodoForm addTodo={addTodo} /> }
10- Updated App.js
import React, { useState } from 'react';
import './App.css';
import TodoTable from './components/TodoTable';
import NewTodoForm from './components/NewTodoForm';
function App() {
const [showAddTodoForm, setShowAddTodoForm] = useState(false);
const [todos, setTodos] = useState([
{ rowNumber: 1, rowDescription: 'Feed puppy', rowAssigned: 'User One' },
{ rowNumber: 2, rowDescription: 'Water plants', rowAssigned: 'User Two' },
{ rowNumber: 3, rowDescription: 'Make dinner', rowAssigned: 'User One' },
{ rowNumber: 4, rowDescription: 'Charge phone battery', rowAssigned: 'User One' }
]
)
const addTodo = (description, assigned) => {
let rowNumber = 0;
if (todos.length > 0) {
rowNumber = todos[todos.length - 1].rowNumber + 1;
} else {
rowNumber = 1;
}
const newTodo = {
rowNumber: rowNumber,
rowDescription: description,
rowAssigned: assigned
};
setTodos(todos => [...todos, newTodo])
}
const deleteTodo = (deleteTodoRowNumber) => {
let filtered = todos.filter(function (value) {
return value.rowNumber !== deleteTodoRowNumber;
});
setTodos(filtered);
}
return (
<div className='mt-5 container'>
<div className="card">
<div className="card-header">
Your Todo's
</div>
<div className="card-body">
<TodoTable todos={todos} deleteTodo={deleteTodo} />
<button onClick={() => setShowAddTodoForm(!showAddTodoForm)} className='btn btn-primary'>
{showAddTodoForm ? 'Close New Todo' : 'New Todo'}
</button>
{showAddTodoForm &&
<NewTodoForm addTodo={addTodo} />
}
</div>
</div>
</div>
);
}
export default App;
11- Updated TodoRowItem.js
function TodoRowItem(props) {
return (
<tr onClick={() => props.deleteTodo(props.rowNumber)}>
<th scope="row">{props.rowNumber}</th>
<td>{props.rowDescription}</td>
<td>{props.rowAssigned}</td>
</tr>
)
}
export default TodoRowItem
No comments:
Post a Comment