+1

Xây dựng ứng dụng react cơ bản P2

Cài đặt thêm package

Ở phần trước chúng ta đã tạo cấu trúc ứng dụng cơ bản như sau Chúng ta thêm folder theo cấu trúc như sau:

|----pages
|--------Add
|------------index.js
|--------Info
|------------index.js
|--------Home
|------------detail.js

Giờ mình import thêm thư viện react-route-dom một thư viện giúp chúng ta điều hướng URL để sử dụng và axios thư viện giúp ta gửi các request http, các bạn nhớ thêm vào package.json và chạy lệnh

npm install

package.json

{
  "name": "my-react-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "axios": "^0.17.1",
    "react": "^16.0.0",
    "react-dom": "^16.0.0",
    "react-router-dom": "^4.2.2",
    "react-scripts": "1.0.14"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  }
}

Viết lại component

ở phần này mình đã sử dụng các REST API đã được xây dựng sẵn cho việc CRUD .. các bạn tham khảo thêm trên mạng nếu chưa biết tạo api bây giờ chúng ta sẽ viết lại các component :

import React, {Component} from 'react';
import { Link } from 'react-router-dom';

class Header extends Component {
    render() {
        return(
            <nav className="navbar navbar-inverse">
              <div className="container-fluid">
                <div className="navbar-header">
                  <button type="button" className="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">
                    <span className="icon-bar"></span>
                    <span className="icon-bar"></span>
                    <span className="icon-bar"></span>
                  </button>
                  <Link to="/" className="navbar-brand">Logo</Link>
                </div>
                <div className="collapse navbar-collapse" id="myNavbar">
                  <ul className="nav navbar-nav">
                    <li className="active"><Link to="/">Home</Link></li>
                    <li><Link to='/add'>Add</Link></li>
                    <li><Link to='/info'>About</Link></li>
                  </ul>
                  <ul className="nav navbar-nav navbar-right">
                    <li><a href="#"><span className="glyphicon glyphicon-log-in"></span> Login</a></li>
                  </ul>
                </div>
              </div>
            </nav>
        );
    }
}

export default Header;

Link được sử dụng để điều hướng bên trong các route nội. Nó tương đương với thẻ <a></a>. Tham số được truyền vào Link là "to", nhận vào đường dẫn url.

import React, {Component} from 'react';

class Footer extends Component {
    render() {
        return(
            <footer className="container-fluid text-center">
                <p>Footer Text</p>
            </footer>
        );
    }
}

export default Footer;

student.js item list của student

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';

class Student extends Component {
    render() {
        return(
            <tr className="">
              <td><Link to={`/student/${ this.props.id }` } className="navbar-brand">{ this.props.name }</Link></td>
              <td>{ this.props.age }</td>
              <td>{ this.props.email }</td>
            </tr>
        );
    }
}

export default Student;

Edit

detail.js page hiển thị chi tiết 1 student và edit

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import Student from '../../components/Student';
import axios from 'axios';

class Detail extends Component {
    constructor(props) {
        super(props);
        this.state = {
            name:'',
            age:'',
            email:''
        }
        this.change = this.change.bind(this);
        this.update = this.update.bind(this);
    }

    componentDidMount() {
      axios.get(`http://laravel54.local.com/api/student/`+ this.props.id).then(res => {
        this.setState({
            name : res.data.name,
            age : res.data.age,
            email : res.data.email,
        })
      }).catch(err => {
        console.log(err.response)
      });
    }

    update(){
        axios.put(`http://laravel54.local.com/api/student/`+this.props.id, {
            name: this.state.name,
            age: this.state.age,
            email: this.state.email,
        }).then(res => {
            alert('update success!')
        }).catch(err => {
            console.log(err.response)
        });
    }

    change(event){
        const target = event.target;
        const value = target.value;
        const name = target.name;
        this.setState({
            [name]: value
        })
    }

    render() {
        return(
            <div className="container-fluid text-center">
              <div className="row content">

                <div className="col-sm-10 col-sm-offset-1 text-left">
                    <h1>Detail page</h1>
                    <div class="form-group">
                        <label for="exampleInputPassword1">Name</label>
                        <input type="text" class="form-control" name="name" value={this.state.name} onChange={this.change} />
                    </div>
                    <div class="form-group">
                        <label for="exampleInputPassword1">Age</label>
                        <input type="text" class="form-control" name="age" value={this.state.age} onChange={this.change} />
                    </div>
                    <div class="form-group">
                        <label for="exampleInputPassword1">Email</label>
                        <input type="text" class="form-control" name="email" value={this.state.email} onChange={this.change}/>
                    </div>

                    <button class="btn btn-default" onClick={this.update}>Update</button>
                </div>

              </div>
            </div>
        );
    }
}

export default Detail;

dữ liệu của 1 student sẽ được hiển thị ở property value của các input ...{this.state.age} v.v.. nên cần lấy dữ liệu và gán vào các biến ở state ta gửi request để lấy 1 sinh viên trong hàm componentDidMount()... hàm sẽ được gọi sau khi render và setStatus khi có dữ liệu trả về khi muốn thay đổi dữ liệu ở textbox ta phải set lại state bằng sự kiện onchange ta viêt thêm hàm update để xử lí update dữ liệu khi nhấn button, cú pháp của axios thì các bạn tự tìm hiểu trên

List

Home/index.js page hiển thị danh sách student

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import Student from '../../components/Student';
import axios from 'axios';

class Home extends Component {
    constructor(){
      super();
      this.state = {
        students:[]
      }
    }

    componentDidMount() {
      axios.get(`http://laravel54.local.com/api/students`).then(res => {
        this.setState({
          students : res.data,
        })
      }).catch(err => {
        console.log(err.response)
      });
    }

    render() {
        return(
            <div className="container-fluid text-center">
              <div className="row content">

                <div className="col-sm-10 col-sm-offset-1 text-left">
                  <h1>Welcome Home page</h1>
                  <table className="table">
                    <thead>
                      <tr>
                        <th>Name</th>
                        <th>Age</th>
                        <th>Email</th>
                      </tr>
                    </thead>
                    <tbody>
                        {this.state.students.map((item,index) =>
          <Student key = {index} id={item.id} name={item.name} age={item.age} email={item.email} ></Student>
        )}
                    </tbody>
                  </table>

                </div>

              </div>
            </div>
        );
    }
}

export default Home;

ở trang home nầy mình sẽ list ra danh sách Student có trong database, nên ta gọi request get all Student viết trong function componentDidMount() , và set lại state ...khi state thay đổi dữ liệu student sẽ được render bằng hàm map

Add

Add/index.js tạo mới 1 student

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import axios from 'axios';

class Add extends Component {
    add() {
      axios.post(`http://laravel54.local.com/api/student`,{
        name : document.getElementsByName('name')[0].value,
        age : document.getElementsByName('age')[0].value,
        email : document.getElementsByName('email')[0].value
      }).then(res => {
        alert('create success')
      }).catch(err => {
        alert('create unsuccess')
        console.log(err.response)
      });
    }
    render() {
        return(
            <div className="container-fluid text-center">
                <div className="row content">

                    <div className="col-sm-10 col-sm-offset-1 text-left">
                        <h1>Add Student</h1>
                        <div class="form-group">
                            <label for="exampleInputPassword1">Name</label>
                            <input type="text" class="form-control" name="name"/>
                        </div>
                        <div class="form-group">
                            <label for="exampleInputPassword1">Age</label>
                            <input type="text" class="form-control" name="age"/>
                        </div>
                        <div class="form-group">
                            <label for="exampleInputPassword1">Email</label>
                            <input type="text" class="form-control" name="email"/>
                        </div>
                        <button onClick={this.add}>Add</button>
                    </div>

              </div>
            </div>
        );
    }
}

export default Add;

Source code tham khảo (branch react_part_2): Một số hình ảnh khi running:


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí