Udemy24 Logo Liight

ساخت یک برنامه ToDo ساده با استفاده از React

اگر هیچ دانشی از React  ندارید می توانید با مراجعه به دوره های آموزشی React و یا وبلاگ, این Framework جذاب و قدرتمند رو یاد بگیرید.

در این مطلب قصد دارم بهتون آموزش بدم که چطور در React یک برنامه ToDo ساده رو به وجود بیارید و کارهاتون رو با اون مدیریت کنید.

این آموزش خیلی ساده و مقدماتی خواهد بود و انتظار استفاده از State management ها مثل Redux و Flux رو نداشته باشید. در این مقاله فقط بر روی React تمرکز میکنیم و سعی میکنیم که همه کارها رو با استفاده از اون انجام بدیم.

برای راه اندازی این پروژه از create-react-app استفاده میکنیم و میتونین این مقاله رو ببینید که چطور میتونین از این ابزار قدرتمند استفاده کنید.

در ابتدا در دایرکتوری public فایل index.html رو باز کرده و کدهای زیر رو درون اون قرار بدین:

<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”utf-8″>
<meta name=”viewport” content=”width=device-width, initial-scale=1, shrink-to-fit=no”>
<link rel=”stylesheet” href=”https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css” integrity=”sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS” crossorigin=”anonymous”>
<title>ToDo App</title>
</head>
<body>
<div class=”container”>
<div id=”root” class=”col-md-8″></div>
</div>
</body>
</html>

همونطور که میبینید ساختار ساده‌ای رو به عنوان ریشه سایت قرار دادیم و در اینجا از bootstrap 4.2.1 استفاده کردیم. همونطور که میبینید یکی از div ها id = root داره. برای شروع کار یک فایل بنام TodoApp.js در دایرکتوری src ساخته و کدهای زیر رو در اون قرار میدم:

import React from ‘react’;

const TodoApp = () => {
return (
<div>Hello World!</div>
);
};

export default TodoApp
همونطور که میبینید یک کد HTML ساده رو در اون return کردیم. حالا در دایرکتوری src، فایل index.js رو باز میکنیم و کدهای زیر رو درونش قرار میدم:

import React from ‘react’;
import ReactDOM from ‘react-dom’;
import TodoApp from ‘./TodoApp’;

ReactDOM.render(<TodoApp />, document.getElementById(‘root’));

همونطور که میبینید TodoApp رو وارد پروژه کرده و با استفاده از متد render از React-dom اون رو در المنت با id = root رندر کردیم. حالا اگر در command line دستور npm start رو بزنید، خروجی در مرورگر بهتون نمایش داده میشه و Hello World رو خواهید دید.

در این مطلب یک برنامه Todo ساده رو میخوایم بسازیم و قصد داریم با استفاده از LocalStorage اطلاعات اون رو مدیریت میکنیم. همونطور که میدونین component ها در React نقش خیلی مهمی رو ایفا میکنند و ما در این مطلب از presentation component استفاده میکنیم. همچنین از PureComponent نیز استفاده خواهیم کرد.

خروجی برنامه در انتها بصورت زیر خواهد بود:

همونطور که میبینید در حال حاضر ۳ مورد در لیست وجود دارد.

متخصص جاوا اسکریپت
با جاوا اسکریپت جادوگری کنید!
آیا می دونید با زبان جاوااسکریپت می تونید، برای فرانت اند و بک اند وبسایت ها برنامه نویسی کنید؟ همینطور اپلیکیشن دسکتاپ و موبایل بسازید؟ اگر دوست داری اینکارها رو انجام بدی و React, ElectronJS, ReactNative, NodeJS,MongoDB و … رو تو یه دوره یاد بگیری، متخصص جاوااسکریپت سون لرن رو حتما ببین :
برای عنوان Todo یک component بنام Title به وجود میاریم و تعداد todo ها رو به اون پاس میدیم تا اون رو نشون بده.
در این قسمت یک component بنام TodoForm به وجود میاریم که در اون یک input و یک button وجود داره و میتونین متن مورد نظرتون رو وارد کرده و بر روی + کلیک کنید تا یک آیتم به Todo ها اضافه بشه.
در این قسمت یک component بنام TodoList به وجود میاریم که لیستی از component های Todo رو در خودش جا میده. میخوایم کاری کنیم که اگر بر روی هر کدام از Todo ها کلیک شد، اون Todo حذف بشه.
more بیشتر بخوانید : افکت زیبا برای دکمه – Distorted Button Effects (نمونه ۸)
در نهایت باید همه component های بالا رو در TodoApp.js وارد کرده و از اونا در جاهای مورد نظر استفاده کنیم. در ابتدا با Title شروع میکنیم. در دایرکتوری components یک فایل بنام Title.js بسازید و کدهای زیر رو درون اون قرار بدین:

import React from ‘react’;

const Title = ({ todoCount }) => {
return (
<div>
<div>
<h1>to-do ({todoCount})</h1>
</div>
</div>
);
};

export default Title;

همونطور که میبینید این component یک props بنام todoCount رو دریافت میکنه و اون رو در یک h1 نمایش میده. حالا از این Component در TodoApp.js استفاده میکنیم. بصورت زیر:

import React, { PureComponent } from ‘react’;

import Title from ‘./components/Title’;

class TodoApp extends PureComponent {
constructor(props) {
// Pass props to parent class
super(props);

// Set initial state
this.state = {
todos: [],
};
}

render() {
// Render JSX
return (
<div>
<Title todoCount={this.state.todos.length} />
</div>
);
}
}

export default TodoApp;

میبینید که در state مقدار اولیه todos رو یک آرایه خالی قرار دادیم و برای کامپوننت Title هم تعداد اعضای این آرایه رو ارسال کردیم. با این کار خروجی در مرورگر بصورت زیر خواهد شد:

همونطور که میبینید در حال حاضر عدد ۰ نشون داده میشه چون task ای در state وجود ندارد. در componentDidMount کدهای زیر رو قرار میدیم:

componentDidMount(){
const todos = JSON.parse(window.localStorage.getItem(‘todos’));

if (todos) {
this.setState({
todos,
});
}
}

همونطور که میبینید در ابتدا چک شده که todos در localStorage وجود داره یا خیر. اگر وجود داشته باشه اعضای اون در state قرار میگیرن و ما میتونیم اونا رو ببینیم.

حالا میخوایم کامپوننت TodoForm رو که وظیفه اون ساختن todo جدید هست رو بسازیم. برای اینکار کدهای زیر رو در فایل TodoForm.js در دایرکتوری component قرار میدیم:

import React from ‘react’;

const TodoForm = ({addTodo}) => {
// Input tracker
let input;

return (
<div className=”input-group mb-3″>
<input
type=”text”
className=”form-control”
ref={node => input = node}
placeholder=”Todo title”
aria-label=”Todo title”
/>

<div className=”input-group-append”>
<button
className=”btn btn-outline-secondary”
type=”button”
onClick={() => {
addTodo(input.value);
input.value = ”;
}}
>
+
</button>
</div>
</div>
);
};

export default TodoForm;

همونطور که میبینید این component یک props بنام addTodo داره که از پدرش به اون پاس داده میشه که بعدا ساختار اون رو بهتون توضیح میدم. این کامپوننت ساده فقط یک input و یک button رو در خودش جا داده و زمانی که بر روی دکمه + کلیک میشه، متد addTodo فراخوانی میشه و مقدار فعلی input به اون پاس داده میشه. در این component از ref نیز استفاده شده است.

more بیشتر بخوانید : آپلود یکباره تمامی محتویات دایرکتوری با webkitdirectory
برای نمایش لیست وظایف به کامپوننت TodoList نیاز داریم. برای اینکار کدهای زیر رو در این کامپوننت قرار میدیم:

import React from ‘react’;

import Todo from ‘./Todo’;

const TodoList = ({todos, remove}) => {
// Map through the todos
const todoNode = todos.map((todo) => {
return (
<Todo todo={todo} key={todo.id} remove={remove}/>
);
});

return (
<ul
className=”list-group”
style={{marginTop:’30px’}}
>
{todoNode}
</ul>
);
};

export default TodoList;

همونطور که میبینید در این کامپوننت از Todo استفاده شده که در ادامه اون رو به وجود خواهیم آورد. ساختار کامپوننت Todo نیز بصورت زیر است:

import React from ‘react’;

const Todo = ({todo, remove}) => {
// Each Todo
return (
<li
className=”list-group-item”
onClick={remove(todo.id)}
>
{todo.text}
</li>
);
};

export default Todo;

میبینید که برای هر Todo یک onClick تعریف شده که با کلیک کردن بر روی اون متد remove که از پدرش به اون پاس داده شده است، مورد استفاده قرار میگیره. متد addTodo بصورت زیر میباشد:

addTodo = (val) => {
// Assemble data
const todo = { text: val, id: window.id++ };

const todos = window.localStorage.getItem(‘todos’);

if (todos === null) {
const todos = [];
todos.push(todo);

window.localStorage.setItem(‘todos’, JSON.stringify(todos));
} else {
const oldTodos = JSON.parse(todos);
oldTodos.push(todo);

// then reset the localStorage
window.localStorage.setItem(‘todos’, JSON.stringify(oldTodos));
}

const newTodos = [
…this.state.todos,
todo,
];

this.setState({todos: newTodos});
}

همونطور که میبینید در اینجا در ابتدا چک شده که چیزی در localStorage وجود داره یا خیر. اگر وجود داشت یک یک آیتم دیگه به اون پاس داده میشه و به روز رسانی میشه. اگر اصلا وجود نداشته باشه هم ساخته میشه.

متد handleRemove نیز بصورت زیر هست:

more بیشتر بخوانید : افکت زیبا برای هاور – Stack Motion Hover ( نمونه ۵)

handleRemove = (id) => () => {
// Filter all todos except the one to be removed
const remainder = this.state.todos.filter((todo) => {
if(todo.id !== id) return todo;
});

window.localStorage.setItem(‘todos’, JSON.stringify(remainder));

this.setState({
todos: remainder,
});
}

همونطور که میبینید در ابتدا todo مورد نظر در State پیدا شده و فیلتر میشه و state و localStorage به روز رسانی میشن. در نهایت اگر بخوایم از همه component ها در کنار هم در فایل TodoApp.js استفاده کنیم، بصورت زیر خواهد شد:

import React, { PureComponent } from ‘react’;

import TodoForm from ‘./components/TodoForm’;
import Title from ‘./components/Title’;
import TodoList from ‘./components/TodoList’;

window.id = ;
class TodoApp extends PureComponent {
constructor(props) {
// Pass props to parent class
super(props);

// Set initial state
this.state = {
todos: [],
};
}

// Lifecycle method
componentDidMount(){
const todos = JSON.parse(window.localStorage.getItem(‘todos’));

if (todos) {
this.setState({
todos,
});
}
}

// Add todo handler
addTodo = (val) => {
// Assemble data
const todo = { text: val, id: window.id++ };

const todos = window.localStorage.getItem(‘todos’);

if (todos === null) {
const todos = [];
todos.push(todo);

window.localStorage.setItem(‘todos’, JSON.stringify(todos));
} else {
const oldTodos = JSON.parse(todos);
oldTodos.push(todo);

// then reset the localStorage
window.localStorage.setItem(‘todos’, JSON.stringify(oldTodos));
}

const newTodos = [
…this.state.todos,
todo,
];

this.setState({todos: newTodos});
}

// Handle remove
handleRemove = (id) => () => {
// Filter all todos except the one to be removed
const remainder = this.state.todos.filter((todo) => {
if(todo.id !== id) return todo;
});

window.localStorage.setItem(‘todos’, JSON.stringify(remainder));

this.setState({
todos: remainder,
});
}

render() {
// Render JSX
return (
<div>
<Title todoCount={this.state.todos.length} />
<TodoForm addTodo={this.addTodo}/>
<TodoList
todos={this.state.todos}
remove={this.handleRemove}
/>
</div>
);
}
}

export default TodoApp;

همونطور که دیدید میتونیم با استفاده از React به راحتی هر چیزی که بخوایم رو به Component های کوچکتری تقسیم‌بندی کنیم و به راحتی و خوانایی بالا کدهامون رو به وجود بیاریم.

, , , , ,
نوشته‌های پیشین
React چیست؟
نوشتهٔ بعدی
آموزش ارسال نوتیفیکیشن‌ها در لاراول

Related Posts

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

Fill out this field
Fill out this field
لطفاً یک نشانی ایمیل معتبر بنویسید.

فهرست