+12

HỌC REACTJS THÔNG QUA VÍ DỤ PHẦN 2

1. Mở đầu.

Xin chào các bạn, trong phần 1 của bài Học React thông qua ví dụ phần 1 chúng ta đã cùng nhau đi tạo giao diện sau đó phân chia giao diện thành các component. Hôm nay chúng ta sẽ tiếp tục đi hoàn thành các công việc tiếp theo là tạo mock data và render Item. Các bạn có thể tham khảo bài viết trước của mình theo link sau : PHẦN 1. Dưới đây là nội dung chính của bài viết.

  1. Tạo mock data.
  2. Thêm package UUID.
  3. Hàm Render Item ở App.js.
  4. In giá trị ở Item.js. Nào chúng ta cùng đi vào từng phần 1 nhé.

2. Tạo mock data.

Vì đây là một project cơ bản nên chúng ta sẽ làm việc với các dữ liệu do chính mình tạo ra, cái này gọi là mockdata hay dữ liệu ảo. Các bạn vào folder src và tạo thêm folder mockdata Bên trong folder này ta thêm file nữa tên là Items.js để tạo 1 mảng các đối tượng chứa dữ liệu.


const Items = [
    {
        id: "abc1",
        name: "Tìm thấy mảnh vỡ máy bay rơi ở Iran làm 66 người chết",
        level: 2 // high
    },
    {
        id: "abc2",
        name: "Không còn tranh cướp lộc hoa tre ở lễ hội đền Gióng 2018",
        level: 0 // low
    },
    {
        id: "abc3",
        name: "Hơn 37.000 người nhập viện vì tai nạn giao thông, đốt pháo",
        level: 1 // medium
    },
    {
        id: "abc4",
        name: "Gần 200 người chết vì tai nạn giao thông 7 ngày nghỉ Tết",
        level: 0 // low
    },
    {
        id: "abc5",
        name: "VFF giải ngân 15 tỷ đồng, tiền thưởng tới tay U23 VN trước Tết",
        level: 2 // high
    },
    {
        id: "abc6",
        name: "F1 muốn tổ chức giải đua xe tại Việt Nam vào năm 2020",
        level: 1 // medium
    }
];

export default Items;

3. Thêm package UUID.

Ta thấy ở mảng trên các id đều là do mình tự đặt, chúng ta có thể sử dụng thêm package uuid để nó tự sinh mã id, các bạn có thể tham khảo thêm về package này tại https://www.npmjs.com/package/uuid .ĐỂ thêm package này trước tiên ta phải dừng chạy project, quay lại màn hình cmd và nhấn tổ hợp phím Ctrl + C, nhấn Y và nhấn enter để xác nhận dừng chạy project. Để thêm package ta gõ vào dòng sau npm install uuid --save . Sau khi đã add xong chúng ta chạy lại project của mình bằng cách gõ npm star. Trong package có nhiều kiểu uuid khác nhau, chúng ta sẽ import uuidv4 để nó sinh ra mã ngẫu nhiên và gắn vào giá trị của các id như code bên dưới.

import uuidv4 from 'uuid/v4';

const Items = [
    {
        id: uuidv4(),
        name: "Tìm thấy mảnh vỡ máy bay rơi ở Iran làm 66 người chết",
        level: 2 // high
    },
    {
        id: uuidv4(),
        name: "Không còn tranh cướp lộc hoa tre ở lễ hội đền Gióng 2018",
        level: 0 // low
    },
    {
        id: uuidv4(),
        name: "Hơn 37.000 người nhập viện vì tai nạn giao thông, đốt pháo",
        level: 1 // medium
    },
    {
        id: uuidv4(),
        name: "Gần 200 người chết vì tai nạn giao thông 7 ngày nghỉ Tết",
        level: 0 // low
    },
    {
        id: uuidv4(),
        name: "VFF giải ngân 15 tỷ đồng, tiền thưởng tới tay U23 VN trước Tết",
        level: 2 // high
    },
    {
        id: uuidv4(),
        name: "F1 muốn tổ chức giải đua xe tại Việt Nam vào năm 2020",
        level: 1 // medium
    }
];

export default Items;

4. Hàm Render Item ở App.js.

Bước 1: Trước tiên chúng ta phải import các dữ liệu mockdata ở Items.js vào trong file App.js.

import Items from './mockdata/Items';

Bước 2 : Sau đó chúng ta sẽ cho Items vào làm một state ở trong constructor của App.js.

constructor(props) {    
    super(props);
    this.state = {
        items: Items
    }
}

Bước 3: Tiếp theo ta viết một hàm là renderItem có nhiệm vụ tách dữ liệu mảng trên và tương ứng với mỗi đối tượng trong mảng sẽ là một Component Item, cách viết hàm dưới đây và về sau này đều sử dụng cách viết của ES6.

renderItem = () => {
    return(111);
}

Bước 4 : Tiếp theo ta sẽ gọi hàm này bên trong đoạn tbody vì các sản phẩm sinh ra sẽ nằm bên trong đó.

<tbody>
    {this.renderItem()}
</tbody>

Bước 5: Trong phương thức renderItem, việc đầu tiên là ta phải lấy được state items chứa mảng dữ liệu.

renderItem = () => {
    let {items} = this.state;
}

Bước 6 : Ta sử dụng hàm map để duyệt mảng items.

renderItem = () => {
    let {items} = this.state;
    return items.map((item) => {
        console.log(item);
    });
}

Nếu bạn bấm phím F12 trên trình duyệt Chrome và chọn tab Console thấy in ra được kết quả như ảnh dưới là chúng ta đã sử dụng thành công phương thức map rồi (tất nhiên là id của bạn sinh ra sẽ khác của mình).

Bước 7 : Trước khi in các Component Item vào bên trong hàm map ta phải import chúng vào trước đã.

import Item from './components/Item';

Việc tiếp theo là thay đoạn console.log(item) bằng Component Item đã add ở trên, lưu ý là ta sẽ phải thêm một tham số index trong hàm trả về. Ta sẽ gắn các giá trị trả về tương ứng làm props của Item, index được dùng để đánh số thứ tự, key để tránh trùng mỗi phần tử khi lặp và item để gửi sang in kết quả.

renderItem = () => {
    let {items} = this.state;
    return items.map((item, index) => {
        return (
            <Item
                item={item}
                index={index}
              />
        )
    });
}

Nếu trên trình duyệt in được ra kết quả như này là chúng ta sắp đi đến thành công rồi. .

5 . In trị ở Item.js.

Ở phần trên chúng ta đã gửi các giá trị thông qua props của <Item />, giờ chỉ việc lấy các giá trị đó gắn vào là xong. Mở file Item.js nằm trong folder components Trong hàm render của nó ta phải lấy được các giá trị đã được gửi qua từ file App.js.

render() {
    let {item,index} = this.props;
    return(
        ...
    )
}

Đơn giản nhất là ta in số thứ tự ra trước đã.

render() {
    let {item,index} = this.props;
    return(
        <tr>
            <td className="text-center">
                {index}
            </td>
            ...
        </tr>
    )
}

Tiếp theo là in tên của item, lưu ý item là đối tượng.

render() {
    let {item,index} = this.props;
    return(
        <tr>
            <td className="text-center">
                {index}
            </td>
            <td>
                {item.name}
            </td>
            ...
        </tr>
    )
}

Việc tiếp theo là in giá trị level, cái khó ở đây là giá trị level là số number và tương ứng mỗi giá trị sẽ có một kiểu label khác nhau.

level = 0  ===> class: label-info    ===> text: Low
level = 1  ===> class: label-warning ===> text: Medium
level = 2  ===> class: label-danger  ===> text: High

Để code dễ dàng có lẽ chúng ta nên dùng switch ... case là tốt nhất. Sau một hồi hí hoáy chúng ta có code của toàn bộ file Item.js như sau.

render() {
    let {item,index} = this.props;
    return(
        <tr>
            <td className="text-center">
                {index}
            </td>
            <td>
                {item.name}
            </td>
            ...
        </tr>
    )
}

Việc tiếp theo là in giá trị level, cái khó ở đây là giá trị level là số number và tương ứng mỗi giá trị sẽ có một kiểu label khác nhau.

level = 0  ===> class: label-info    ===> text: Low
level = 1  ===> class: label-warning ===> text: Medium
level = 2  ===> class: label-danger  ===> text: High

Để code dễ dàng có lẽ chúng ta nên dùng switch ... case là tốt nhất. Sau một hồi hí hoáy chúng ta có code của toàn bộ file Item.js như sau.

import React, {Component} from 'react';

class Item extends Component {
    render() {
        let {item,index} = this.props;
        let classNameLabel = '';
        let nameLabel = '';
        switch (item.level) {
            case 1:
                classNameLabel = 'label label-warning';
                nameLabel = 'Medium';
                break;
            case 2:
                classNameLabel = 'label label-danger';
                nameLabel = 'High';
                break;
            default:
                classNameLabel = 'label label-info';
                nameLabel = 'Low';
                break;
        }
        return(
            <tr>
                <td className="text-center">
                    {index}
                </td>
                <td>
                    {item.name}
                </td>
                <td className="text-center">
                    <span className={classNameLabel}>{nameLabel}</span>
                </td>
                <td>
                    <button type="button" className="btn btn-warning btn-sm">Edit</button>
                    <button type="button" className="btn btn-danger btn-sm">Delete</button>
                </td>
            </tr>
        )
    }
}
 
export default Item;

Nếu ngon nghẻ và suôn sẻ không thấy có lỗi gì cả ở trong tab Console thì chúng ta đã in được các dữ liệu ở trong mockdata ra ngoài thành công. Đây là kết quả của chúng ta sau một hồi vất vả. .

6. Tạm kết.

Bài viết này cũng khá dài mình xin dừng lại tại đây, hẹn gặp lại các bạn trong những bài viết tiếp theo. Rất mong được sự ủng hộ và theo dõi của các bạn để mình có thể viết thêm được nhiều bài viết hơn nữa.


All rights reserved

Bình luận

Đăng nhập để bình luận
Avatar
@frost
thg 7 9, 2019 2:49 SA

bạn viết rõ hơn được không nhỉ, người mới học reactjs ko biết viết cái hàm renderItem ở chỗ nào, thấy bảo viết ở App.js nhưng sau lại thấy import './components/Item' ở đâu đâu 😦

Xem thêm (2)
Avatar
@bee
thg 8 30, 2019 7:10 SA

Anh ơi vậy cho em hỏi hàm rederItem ở bên component ListItem đúng không anh ? Mong anh phản hồi ạ

Avatar
@TruongDQ
thg 6 12, 2020 11:52 SA

author update lại đi ạ.. nhiều lúc xem lại mà vẫn chưa thấy

Avatar
@vuatintac
thg 5 14, 2020 5:57 CH

Cho ai đang đứng hình. Ở mục 3 Để vầy ko chạy:

import uuidv4 from 'uuid/v4';

báo lỗi

./src/mockdata/Items.js
Module not found: Can't resolve 'uuid/v4' in 'D:\react\bai-tap-ve-nha\my-app\src\mockdata'

sửa thế này thì chạy

import { v4 as uuidv4 } from 'uuid';

Avatar
@vuatintac
thg 5 14, 2020 6:04 CH

Ở mục 4.4 Nếu thêm này vào ListItem.js thì ko chạy, sẽ báo lỗi

<tbody>
{this.renderItem()}
</tbody>

Giải pháp là import luôn mockdata ItemsItem component vào ListItem.js

import React, {Component} from 'react';
import Items from '../mockdata/Items';
import Item from '../components/Item';

rồi ở Bước 4.2 và Bước 4.3 gắn constructorrenderItem() vào ListItem.js, chứ ko phải App.js

Avatar
@thanlong2910
thg 10 19, 2020 3:32 SA

Đúng vậy đó, cảm ơn bạn nha.

Avatar
@TruongDQ
thg 6 12, 2020 5:32 SA

đùa chứ author viết k rõ như thế newbie có mà mò tới sang năm 😦 k hiểu đc là đang làm ở file nào lẫn file nào

Avatar
@Martin
thg 8 20, 2020 7:26 SA

Ở level newbie, mình nhận thấy phần 2 này không rõ là phải vào file nào để làm theo từng bước như thế nào. Phần 1 thì kỹ càng dễ hiểu hơn. Author nên viết lại rõ ràng hơn để newbie sống với 😄

Avatar
@HuyDevIT
thg 1 28, 2021 3:49 SA

thay vì dùng switch case thì chúng ta có dùng toán tử

<td className="text-center"> {value.level == 0 ? ( <span className="label label-info">Low</span> ) : value.level == 1 ? ( <span className="label label-warning">Medium</span> ) : ( <span className="label label-danger">Hight</span> )} </td>

tôi không dùng class như bài hướng dẫn nên chưa hiểu tại sao lại gọi dến mockData ở app.js trong khi chúng ta lại cần map ở componentItem và tôi dã làm như này: import React, { useState } from "react"; import PropTypes from "prop-types"; import mockData from "../../mockData"; const ComponentItem = (props) => { const [item] = useState(mockData); console.log("item", item); return ( <> {item.map((value, index) => ( <tr key={index}> <td className="text-center">{value.id}</td> <td>{value.name}</td> <td className="text-center"> {value.level == 0 ? ( <span className="label label-info">Low</span> ) : value.level == 1 ? ( <span className="label label-warning">Medium</span> ) : ( <span className="label label-danger">Hight</span> )} </td> <td> <button type="button" className="btn btn-warning btn-sm"> Edit </button> <button type="button" className="btn btn-danger btn-sm"> Delete </button> </td> </tr> ))} </> ); };

ComponentItem.propTypes = {};

export default ComponentItem;

Avatar
@zerox8587
thg 7 17, 2021 2:01 CH

Phần 1 đang ngon lành tự nhiên sang phần 2 này loạn luôn, mấy đoạn code kia không biết viết ở file nào 😦

Avatar
@supert
thg 8 7, 2021 3:20 SA

let {items} = this.state; sẽ trả về một object không thể sử dụng phương thức map() nên sẽ bị lỗi

Avatar
@supert
thg 8 7, 2021 4:41 SA

Thấy nhiều bạn chưa làm được nên mình góp ý theo cách làm của mình nhé, mình cũng newbie nên sai thì các bạn thông cảm 😄 Các bạn lưu ý mình có sửa lại một vài chỗ, Số 1 là this.state nó là object nên không dùng phương thức map() được, mình phải lấy cụ thể this.state.items ( mảng) thì mới duyệt mảng được, chỗ thứ 2 là mình đổi tên props của Item thành itemArg ( ở đây Component giống như một funtion với 2 tham số là itemArg vs indexArg được gán giá trị là item và index) 2021-08-07_114251.png Ở component item mình dựa theo cách xử lý của tác giả tách phần xử lý label ra thành một phương thức riêng xử lý 2021-08-07_114011.png

Avatar
@buiquan
thg 8 11, 2021 10:02 SA

thanks bạn nhé

Cho mình hỏi constructor này trong ListItem.js constructor(props, context)

thì context có ý nghĩa gì ko? Ở đây, mình thấy bỏ nó đi vẫn ok

Avatar
@supert
thg 8 12, 2021 3:31 CH

@buiquan Sr bạn, như mình nói ở trên, mình cũng newbie,mới dừng ở mức sử dụng chưa đi sâu vào mấy cái này, biết cái gì thì mình share cái đấy

Avatar
@dangminh47
thg 6 3, 2022 2:48 SA

Bài viết nó chán vcc, viết lung tung từ component này qua component khác khó hiểu vl

Avatar
+12
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í