در این مقاله قصد داریم نحوه انجام عملیات CRUD در react.js را به شما آموزش دهیم. تقریباً اکثر برنامه ها نیاز به انجام عملیات crud دارند. CRUD مخفف Create و Read ,Update ,Delete است.
به این برنامه ها MERN Stack هم گفته می شود، چون ما از تکنولوژی های MongoDB ,Express ,React ,Node.js استفاده می کنیم. در این برنامه کاربران می توانند اطلاعاتشان را ویرایش یا حذف کرده و همچنین آنها را مشاهده کنند و یا اینکه اطلاعات جدید را وارد برنامه بکنند.
React.js یک کتابخانه مربوط به طراحی رابط کاربری بوده و یک فریم ورک کامل مانند انگولار نیست. ری اکت یک کتابخانه جاوا اسکریپت برای ساخت رابط کاربری است که توسط فیسبوک ساخته و پشتیبانی می شود. با مطالعه لینک زیر می توانید به تفاوت اساسی بین ری اکت و انگولار پی ببرید:
برای کسب اطلاع بیشتر درباره این کتابخانه به مستندات رسمی آن مراجعه کنید.
React.js به شما اجازه می دهد ظاهر برنامه تان را در هر نقطه از زمان مشخص کنید. به محض انجام تغییر در داده ها، ری اکت به طور خودکار تمام بروزرسانی های رابط کاربری را مدیریت می کند. هنگامی که داده ها تغییر می کند، ری اکت به طور ضمنی دکمه refresh را فشار می دهد و تنها آن بخشی که تغییر کرده را بروزرسانی می کند.
دلایل اصلی استفاده از ری اکت به شرح زیر است:
بجز فیسبوک و اینستاگرام، شرکت های زیادی از قبیل DropBox ،Paypal ،Netflix ،Airbnb و... از ری اکت استفاده می کنند.
در این آموزش از تکنولوژی های زیر استفاده می کنیم.
ترمینال را باز کرده و با دستور زیر یک برنامه جدید ری اکت ایجاد کنید.
npx create-react-app reactcrud cd reactcrud npm start
در صورتی که هنگام کامپایل کدها با یک خطا مواجه شدید، یک فایل با نام .env در روت پروژه ایجاد کرده و کد زیر را در آن قرار دهید.
SKIP_PREFLIGHT_CHECK=true
حال مرورگر را باز کرده و به آدرس localhost:3000 بروید.
حال با دستور زیر بوت استرپ 4 را نصب کنید.
yarn add bootstrap # or npm install bootstrap --save
فایل src/App.js را باز کرده و مانند زیر فایل css بوت استرپ را به آن import کنید.
// App.js import React, { Component } from 'react'; import 'bootstrap/dist/css/bootstrap.min.css'; class App extends Component { render() { return ( <div className="container"> <h2>React CRUD Tutorial</h2> </div> ); } } export default App;
دستورات زیر را برای نصب ماژول react-router-dom در ترمینال اجرا کنید.
در صورتی که مایل به کسب اطلاع بیشتر درباره ماژول react-router-dom هستید به مستندات رسمی آن مراجعه کنید.
yarn add react-router-dom # or npm install react-router-dom --save
فایل index.js را باز کرده و کامپوننت App.js را بین آبجکت BrowserRouter قرار دهید.
// index.js import React from 'react'; import ReactDOM from 'react-dom'; import { BrowserRouter } from 'react-router-dom'; import App from './App'; import * as serviceWorker from './serviceWorker'; ReactDOM.render( <BrowserRouter> <App /> </BrowserRouter>, document.getElementById('root')); serviceWorker.unregister();
یک فولدر به نام Components داخل فولدر src ایجاد کنید و داخل این فولدر سه کامپوننت به نام های زیر قرار دهید:
// create.component.js import React, { Component } from 'react'; export default class Create extends Component { render() { return ( <div> <p>Welcome to Create Component!!</p> </div> ) } }
// edit.component.js import React, { Component } from 'react'; export default class Edit extends Component { render() { return ( <div> <p>Welcome to Edit Component!!</p> </div> ) } }
// index.component.js import React, { Component } from 'react'; export default class Index extends Component { render() { return ( <div> <p>Welcome to Index Component!!</p> </div> ) } }
حال می خواهیم یک منوی پیمایشی به برنامه مان اضافه کنیم. برای اینکار کدهای زیر را در فایل App.js قرار دهید.
// App.js import React, { Component } from 'react'; import 'bootstrap/dist/css/bootstrap.min.css'; import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom'; import Create from './components/create.component'; import Edit from './components/edit.component'; import Index from './components/index.component'; class App extends Component { render() { return ( <Router> <div className="container"> <nav className="navbar navbar-expand-lg navbar-light bg-light"> <Link to={'/'} className="navbar-brand">React CRUD Example</Link> <div className="collapse navbar-collapse" id="navbarSupportedContent"> <ul className="navbar-nav mr-auto"> <li className="nav-item"> <Link to={'/'} className="nav-link">Home</Link> </li> <li className="nav-item"> <Link to={'/create'} className="nav-link">Create</Link> </li> <li className="nav-item"> <Link to={'/index'} className="nav-link">Index</Link> </li> </ul> </div> </nav> <br/> <h2>Welcome to React CRUD Tutorial</h2> <br/> <Switch> <Route exact path='/create' component={ Create } /> <Route path='/edit/:id' component={ Edit } /> <Route path='/index' component={ Index } /> </Switch> </div> </Router> ); } } export default App;
فایل را ذخیره کرده و به مرورگر برگردید
فایل create.component.js را باز کرده و کدهای زیر را برای ساخت یک فرم بوت استرپ در آن قرار دهید.
// create.component.js import React, { Component } from 'react'; export default class Create extends Component { render() { return ( <div style={{marginTop: 10}}> <h3>Add New Business</h3> <form> <div className="form-group"> <label>Add Person Name: </label> <input type="text" className="form-control"/> </div> <div className="form-group"> <label>Add Business Name: </label> <input type="text" className="form-control"/> </div> <div className="form-group"> <label>Add GST Number: </label> <input type="text" className="form-control"/> </div> <div className="form-group"> <input type="submit" value="Register Business" className="btn btn-primary"/> </div> </form> </div> ) } }
همان طور که در بالا دیدید ما یک فرم با سه فیلد برای ورود اطلاعات ایجاد کردیم. این فیلد عبارتند از :
حال باید چهار متد برای بررسی تغییرات این فیلدها ایجاد کنیم و یک سری state برای آنها تنظیم کنیم.
همچنین این چهار متد یک درخواست post به سرور node express ارسال می کنند. حال ابتدا یک سازنده تعریف کرده و یک وضعیت (state) اولیه را برای آن تنظیم می کنیم، سپس این وضعیت را به رویداد های مختلف داخل سازنده متصل می کنیم.
سپس توابعی را برای بررسی تغییرات هر فیلد input تعریف می کنیم. به این ترتیب هنگامی که کاربر شروع به تایپ داخل این textbox ها بکند، state را مطابق با آن تنظیم می کنیم.
فرض کنید اگر کاربر نام شخصی اش را وارد textbox کند، آنگاه ما مقدار وضعیت مربوط به نام شخصی (person name) را تغییر می دهیم.
در نهایت هنگام ارسال فرم، مقادیر را از state گرفته و آن را توسط یک درخواست post به سرور ارسال می کنیم.
// App.js import React, { Component } from 'react'; export default class Create extends Component { constructor(props) { super(props); this.onChangePersonName = this.onChangePersonName.bind(this); this.onChangeBusinessName = this.onChangeBusinessName.bind(this); this.onChangeGstNumber = this.onChangeGstNumber.bind(this); this.onSubmit = this.onSubmit.bind(this); this.state = { person_name: '', business_name: '', business_gst_number:'' } } onChangePersonName(e) { this.setState({ person_name: e.target.value }); } onChangeBusinessName(e) { this.setState({ business_name: e.target.value }) } onChangeGstNumber(e) { this.setState({ business_gst_number: e.target.value }) } onSubmit(e) { e.preventDefault(); console.log(`The values are ${this.state.person_name}, ${this.state.business_name}, and ${this.state.business_gst_number}`) this.setState({ person_name: '', business_name: '', business_gst_number: '' }) } render() { return ( <div style={{ marginTop: 10 }}> <h3>Add New Business</h3> <form onSubmit={this.onSubmit}> <div className="form-group"> <label>Person Name: </label> <input type="text" className="form-control" value={this.state.person_name} onChange={this.onChangePersonName} /> </div> <div className="form-group"> <label>Business Name: </label> <input type="text" className="form-control" value={this.state.business_name} onChange={this.onChangeBusinessName} /> </div> <div className="form-group"> <label>GST Number: </label> <input type="text" className="form-control" value={this.state.business_gst_number} onChange={this.onChangeGstNumber} /> </div> <div className="form-group"> <input type="submit" value="Register Business" className="btn btn-primary"/> </div> </form> </div> ) } }
یک فولدر به نام api در روت پروژه ایجاد و با اجرای دستور زیر در ترمینال، فایل package.json را مقداردهی اولیه می کنیم.
npm init -y
حال وابستگی های Node.js را نصب می کنیم.
yarn add express body-parser cors mongoose # or npm install express body-parser cors mongoose --save
همچنین nodemon را به عنوان یک وابستگی توسعه (development Dependency) نصب کنید. با اینکار، با انجام هر تغییر در کدهای سمت سرور، نیازی به راه اندازی مجدد سرور نداریم.
npm install nodemon --save-dev
حال داخل فولدر api یک فایل با نام server.js ایجاد کنید و کدهای زیر را در آن قرار دهید.
// server.js const express = require('express'); const app = express(); const bodyParser = require('body-parser'); const PORT = 4000; const cors = require('cors'); app.use(cors()); app.use(bodyParser.urlencoded({extended: true})); app.use(bodyParser.json()); app.listen(PORT, function(){ console.log('Server is running on Port:',PORT); });
یک تب جدید در ترمینال باز کرده (در ویندوز، ترمینال قبلی را باز نگه داشته و یک ترمینال جدید باز کنید) و دستور زیر را در آن اجرا کنید.
nodemon server
همان طور که در تصویر زیر می بینید، سرور node در حال اجراست .
من قبلاً MongoDB را روی سیستم عامل مک نصب کرده بودم. بنابراین با تایپ دستور زیر در ترمینال، سرور MongoDB را راه اندازی کنید.
mongod
در فولدر api یک فایل با نام DB.js ایجاد کرده و کدهای زیر را در آن قرار دهید.
// DB.js module.exports = { DB: 'mongodb://localhost:27017/reactcrud' }
در پایگاه داده محلی MongoDB من، username و password خالی است، اما در هنگام خروجی نهایی از برنامه، شما باید یک کاربر Admin ایجاد کرده و پایگاه داده را به آن کاربر نسبت دهید.
حال فایل DB.js را به فایل server.js، اضافه یا import کنید.
// server.js const express = require('express'); const app = express(); const bodyParser = require('body-parser'); const PORT = 4000; const cors = require('cors'); const mongoose = require('mongoose'); const config = require('./DB.js'); mongoose.Promise = global.Promise; mongoose.connect(config.DB, { useNewUrlParser: true }).then( () => {console.log('Database is connected') }, err => { console.log('Can not connect to the database'+ err)} ); app.use(cors()); app.use(bodyParser.urlencoded({extended: true})); app.use(bodyParser.json()); app.listen(PORT, function(){ console.log('Server is running on Port:',PORT); });
در مرحله بعد، می خواهیم یک schema برای پایگاه داده MongoDB ایجاد کنیم.
برای اینکار یک فایل با نام business.model.js داخل فولدر api ایجاد کرده و کدهای زیر را در آن قرار دهید.
// business.model.js const mongoose = require('mongoose'); const Schema = mongoose.Schema; // Define collection and schema for Business let Business = new Schema({ person_name: { type: String }, business_name: { type: String }, business_gst_number: { type: Number } },{ collection: 'business' }); module.exports = mongoose.model('Business', Business);
کدهای زیر که مربوط به عملیات Crud است را در فایل business.model.js قرار دهید.
// business.route.js const express = require('express'); const businessRoutes = express.Router(); // Require Business model in our routes module let Business = require('./business.model'); // Defined store route businessRoutes.route('/add').post(function (req, res) { let business = new Business(req.body); business.save() .then(business => { res.status(200).json({'business': 'business in added successfully'}); }) .catch(err => { res.status(400).send("unable to save to database"); }); }); // Defined get data(index or listing) route businessRoutes.route('/').get(function (req, res) { Business.find(function(err, businesses){ if(err){ console.log(err); } else { res.json(businesses); } }); }); // Defined edit route businessRoutes.route('/edit/:id').get(function (req, res) { let id = req.params.id; Business.findById(id, function (err, business){ res.json(business); }); }); // Defined update route businessRoutes.route('/update/:id').post(function (req, res) { Business.findById(req.params.id, function(err, business) { if (!business) res.status(404).send("data is not found"); else { business.person_name = req.body.person_name; business.business_name = req.body.business_name; business.business_gst_number = req.body.business_gst_number; business.save().then(business => { res.json('Update complete'); }) .catch(err => { res.status(400).send("unable to update the database"); }); } }); }); // Defined delete | remove | destroy route businessRoutes.route('/delete/:id').get(function (req, res) { Business.findByIdAndRemove({_id: req.params.id}, function(err, business){ if(err) res.json(err); else res.json('Successfully removed'); }); }); module.exports = businessRoutes;
در بالا عملیات Crud را برای MongoDB تعریف کردیم، بنابراین هنگامی که درخواستی به سرور برسد، سرور آن درخواست را به منبع مناسب هدایت می کند. و با متد بالا عملیات مربوط به پایگاه داده اجرا شده و پاسخ به کلاینت ارسال می شود.
در اینجا ما از Mongoose ORM برای ذخیره، بروزرسانی و حذف داده ها از پایگاه داده ها استفاده می کنیم.
Mongoose یک ORM برای کار با پایگاه داده MongoDB است. حال باید این فایل را به فایل Server.js، اضافه یا import کنیم.در نهایت فایل Server.js ما باید مطابق زیر باشد:
// server.js const express = require('express'); const app = express(); const bodyParser = require('body-parser'); const PORT = 4000; const cors = require('cors'); const mongoose = require('mongoose'); const config = require('./DB.js'); const businessRoute = require('./business.route'); mongoose.Promise = global.Promise; mongoose.connect(config.DB, { useNewUrlParser: true }).then( () => {console.log('Database is connected') }, err => { console.log('Can not connect to the database'+ err)} ); app.use(cors()); app.use(bodyParser.urlencoded({extended: true})); app.use(bodyParser.json()); app.use('/business', businessRoute); app.listen(PORT, function(){ console.log('Server is running on Port:',PORT); });
کتابخانه Axios را برای ارسال درخواست post در برنامه، نصب میکنیم.
yarn add axios # or npm install axios --save
حال یک درخواست post که شامل داده های فرم است را به سرور Node.js ارسال می کنیم. در اینجا داده ها به عنوان یک آبجکت ارسال می شوند، چون در بخش بک اند از یک تجزیه کننده بدنه (body parser) برای تجزیه داده ها از درخواست و ذخیره آن در پایگاه داده استفاده کرده ایم.
کدهای زیر را در فایل create.component.js قرار دهید.
// create.component.js import React, { Component } from 'react'; import axios from 'axios'; export default class Create extends Component { constructor(props) { super(props); this.onChangePersonName = this.onChangePersonName.bind(this); this.onChangeBusinessName = this.onChangeBusinessName.bind(this); this.onChangeGstNumber = this.onChangeGstNumber.bind(this); this.onSubmit = this.onSubmit.bind(this); this.state = { person_name: '', business_name: '', business_gst_number:'' } } onChangePersonName(e) { this.setState({ person_name: e.target.value }); } onChangeBusinessName(e) { this.setState({ business_name: e.target.value }) } onChangeGstNumber(e) { this.setState({ business_gst_number: e.target.value }) } onSubmit(e) { e.preventDefault(); const obj = { person_name: this.state.person_name, business_name: this.state.business_name, business_gst_number: this.state.business_gst_number }; axios.post('http://localhost:4000/business/add', obj) .then(res => console.log(res.data)); this.setState({ person_name: '', business_name: '', business_gst_number: '' }) } render() { return ( <div style={{ marginTop: 10 }}> <h3>Add New Business</h3> <form onSubmit={this.onSubmit}> <div className="form-group"> <label>Person Name: </label> <input type="text" className="form-control" value={this.state.person_name} onChange={this.onChangePersonName} /> </div> <div className="form-group"> <label>Business Name: </label> <input type="text" className="form-control" value={this.state.business_name} onChange={this.onChangeBusinessName} /> </div> <div className="form-group"> <label>GST Number: </label> <input type="text" className="form-control" value={this.state.business_gst_number} onChange={this.onChangeGstNumber} /> </div> <div className="form-group"> <input type="submit" value="Register Business" className="btn btn-primary"/> </div> </form> </div> ) } }
حال مرورگر را باز کنید. یک سری اطلاعات در فرم وارد کرده و فرم را ارسال کنید. نتیجه را در محیط console مرورگر می بینید.
برای دیدن تصاویر ذخیره شده در پایگاه داده، باید یک Mongoshell را اجرا کنیم.
کدهای زیر را در فایل index.component.js قرار دهید.
// index.component.js import React, { Component } from 'react'; import axios from 'axios'; import TableRow from './TableRow'; export default class Index extends Component { constructor(props) { super(props); this.state = {business: []}; } componentDidMount(){ axios.get('http://localhost:4000/business') .then(response => { this.setState({ business: response.data }); }) .catch(function (error) { console.log(error); }) } tabRow(){ return this.state.business.map(function(object, i){ return <TableRow obj={object} key={i} />; }); } render() { return ( <div> <h3 align="center">Business List</h3> <table className="table table-striped" style={{ marginTop: 20 }}> <thead> <tr> <th>Person</th> <th>Business</th> <th>GST Number</th> <th colSpan="2">Action</th> </tr> </thead> <tbody> { this.tabRow() } </tbody> </table> </div> ); } }
در بالا ما یک درخواست Get برای بازیابی داده ها از سرور Node.js ارسال کردیم.
همچنین کامپوننت TableRow.js را به فایل فوق import کردیم. حال کدهای زیر را در آن قرار دهید.
// TableRow.js import React, { Component } from 'react'; class TableRow extends Component { render() { return ( <tr> <td> {this.props.obj.person_name} </td> <td> {this.props.obj.business_name} </td> <td> {this.props.obj.business_gst_number} </td> <td> <button className="btn btn-primary">Edit</button> </td> <td> <button className="btn btn-danger">Delete</button> </td> </tr> ); } } export default TableRow;
این کامپوننت مسئول نمایش سطرهای بازیابی شده از پایگاه داده است. فایل را ذخیره کرده و به آدرس localhost:3000/index بروید.
ابتدا یک Link به فایل TableRow.js اضافه می کنیم.
// TableRow.js import { Link } from 'react-router-dom'; <Link to={"/edit/"+this.props.obj._id} className="btn btn-primary">Edit</Link>
سپس کدهای زیر را به فایل edit.component.js اضافه کنید.
// edit.component.js import React, { Component } from 'react'; import axios from 'axios'; export default class Edit extends Component { constructor(props) { super(props); this.onChangePersonName = this.onChangePersonName.bind(this); this.onChangeBusinessName = this.onChangeBusinessName.bind(this); this.onChangeGstNumber = this.onChangeGstNumber.bind(this); this.onSubmit = this.onSubmit.bind(this); this.state = { person_name: '', business_name: '', business_gst_number:'' } } componentDidMount() { axios.get('http://localhost:4000/business/edit/'+this.props.match.params.id) .then(response => { this.setState({ person_name: response.data.person_name, business_name: response.data.business_name, business_gst_number: response.data.business_gst_number }); }) .catch(function (error) { console.log(error); }) } onChangePersonName(e) { this.setState({ person_name: e.target.value }); } onChangeBusinessName(e) { this.setState({ business_name: e.target.value }) } onChangeGstNumber(e) { this.setState({ business_gst_number: e.target.value }) } onSubmit(e) { e.preventDefault(); const obj = { person_name: this.state.person_name, business_name: this.state.business_name, business_gst_number: this.state.business_gst_number }; axios.post('http://localhost:4000/business/update/'+this.props.match.params.id, obj) .then(res => console.log(res.data)); this.props.history.push('/index'); } render() { return ( <div style={{ marginTop: 10 }}> <h3 align="center">Update Business</h3> <form onSubmit={this.onSubmit}> <div className="form-group"> <label>Person Name: </label> <input type="text" className="form-control" value={this.state.person_name} onChange={this.onChangePersonName} /> </div> <div className="form-group"> <label>Business Name: </label> <input type="text" className="form-control" value={this.state.business_name} onChange={this.onChangeBusinessName} /> </div> <div className="form-group"> <label>GST Number: </label> <input type="text" className="form-control" value={this.state.business_gst_number} onChange={this.onChangeGstNumber} /> </div> <div className="form-group"> <input type="submit" value="Update Business" className="btn btn-primary"/> </div> </form> </div> ) } }
کاری که ما در اینجا انجام دادیم استفاده از متد چرخه حیات کامپوننت ها برای بازیابی داده ها از Api است.
داده های بازیابی شده باید برای انجام ویرایش روی آنها، وارد textbox ها شوند. فایل را ذخیره کنید و به صفحه edit مراجعه کنید.
اگر داده ها نمایش داده نمی شوند، اطمینان حاصل کنید که سرور Node.js در حال اجرا باشد.
در بالا کدهای مربوط به بروزرسانی را هم نوشتیم. در این کدها توسط یک متدی که تعریف کردیم، با ارسال یک درخواست به سرور Node.js، داده هایی که توسط یک id مشخص شده اند را بروزرسانی می کنیم.
در این قسمت، قابلیت حذف داده ها را پیاده سازی می کنیم. برای اینکار متد delete را در فایل TableRow.js تعریف خواهیم کرد.
// TableRow.js import React, { Component } from 'react'; import { Link } from 'react-router-dom'; import axios from 'axios'; class TableRow extends Component { constructor(props) { super(props); this.delete = this.delete.bind(this); } delete() { axios.get('http://localhost:4000/business/delete/'+this.props.obj._id) .then(console.log('Deleted')) .catch(err => console.log(err)) } render() { return ( <tr> <td> {this.props.obj.person_name} </td> <td> {this.props.obj.business_name} </td> <td> {this.props.obj.business_gst_number} </td> <td> <Link to={"/edit/"+this.props.obj._id} className="btn btn-primary">Edit</Link> </td> <td> <button onClick={this.delete} className="btn btn-danger">Delete</button> </td> </tr> ); } } export default TableRow;
به این ترتیب آموزش انجام عملیات Crud در ری اکت یا آموزش MERN Stack مان به پایان رسید.
سورس کدهای این مقاله را می توانید از این آدرس گیت هاب دریافت کنید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.