Tớ đã ăn hành với Redux như thế nào (From topdev.vn)

Alex Nguyen2020-06-13i did itreact-native redux

alt text

Để chuẩn bị cho công cuộc phỏng vấn vì miếng ăn, tớ phải tranh thủ tìm hiểu React và các công nghệ liên quan, trong đó có Redux. Đường cách mạng còn lắm gian truân, đọc document của nó éo hiểu gì hết. Hôm nay chia sẻ với mọi người cách tiếp cận Redux.

Đặt vấn đề

Khi lập trình React, điều đầu tiên bực bội nhất là việc quản lý State. Như hình phía trên, để truyền dữ liệu giữa các component khá là lằng nhằng do chỉ truyền được cho component kề nhau. Do đó, cần có một cơ chế để quản lý state riêng biệt.

Giải pháp

Ok, dễ nhất thì ta cứ xem state như biến toàn cục, khi cần thì viết Get/Set bình thường. Tớ có nghĩ đến localStorage. Tuy nhiên cách này khá bưởi, bạn có thể xem thêm tại đây. Please Stop Using Local Storageopen in new window

Thử cách khác, ta hỏi chị Google. Kết quả là ta được 2 giải pháp đó là Fluxopen in new windowReduxopen in new window. Về phần Flux, ta có thể xem bài tutorial sau đây là hình dung được tư tưởng. Còn Redux, nó khá là hại não. Xem bài Hướng dẫn và giải thích Flux bằng hình vẽopen in new window

Redux

Giờ mới là phần chính. Ta thử vào xem trang chủ của Redux tại https://redux.js.org xem có hiểu gì không nhé. Chắc cú là không dành cho beginner rồi. Tớ phải xem bài viết React Redux Tutorial for Beginners: The Definitive Guide (2018)open in new window mới hình dung được Redux như thế nào.

Về cơ bản, Redux là một thư viện quản lý state, nó độc lập với React. Do đó, Redux có thể sử dụng chung với các thư viện khác vẫn được.

Các thành phần cơ bản của Redux bao gồm:

  1. Store – Nơi lưu trữ state
  2. Actions – Các hành động truyền dữ liệu được gởi từ ứng dụng đến Store
  3. Reducer – Xác định cách thay đổi State

alt

Ăn hành

Bây giờ tớ sẽ minh hoạ cho các bạn hiểu cách chạy bình thường của Redux nhé. Lúc này, ta chỉ đụng mỗi Redux thôi.

alt2

Đầu tiên, Reducer sẽ khởi tạo State và cách xác định thay đổi State. Sau đó, khởi tạo Store bằng Reducer đã khởi tạo trước đó. Lúc này, ta khai báo tiếp hành động.

import { ADD_ARTICLE } from ‘../constants/action-types’
const initialState = {
articles: []
}
const rootReducer = (state = initialState, action) => {
switch (action.type) {
case ADD_ARTICLE:
return { …state, articles: […state.articles, action.payload] }
default:
return state
}
}
export default rootReducer

alt Như bạn đã thấy, phía Store sẽ dispatch thằng ku Actions là State được thay đổi rồi. Như thế, ta có thể cho State tách biệt khỏi mớ Components.

Ăn hành cùng với React

Ban đầu tớ nghĩ chúng ta có thể import Store vào nơi cần gọi là được. Nhưng giang hồ dùng chiêu thức khác, họ mapping State của Components với State của Store. Thặc vi diệu!!! Để triển được chiêu thức đó, ta cần cài thêm package react-redux. Ghi nhớ khẩu quyết của chiêu thức này.

  • mapStateToProps: dùng để map State của Component với State trong Store của Redux
  • mapDispatchToProps: dùng để map method của Component với lời gọi action từ Store tới Actions của Redux Sau đây là cách sử dụng: Redux__ex__mapStateToProps.js
import React from "react";
import { connect } from "react-redux";
import PropTypes from "prop-types";

const mapStateToProps = state => {
    return { articles: state.articles };
};

const ConnectedList = ({ articles }) => (
    <ul className="list-group list-group-flush">
        {articles.map(el => (
            <li className="list-group-item" key={el.id}>
                {el.title}
            </li>
        ))}
    </ul>
);

const List = connect(mapStateToProps)(ConnectedList);

ConnectedList.propTypes = {
    articles: PropTypes.array.isRequired
};

export default List;

Redux__ex__mapDispatchToProps.js

import React, { Component } from "react";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import uuidv1 from "uuid";
import { addArticle } from "../actions/index";

const mapDispatchToProps = dispatch => {
    return {
        addArticle: article => dispatch(addArticle(article))
    };
};

class ConnectedForm extends Component {
    constructor() {
        super();

        this.state = {
            title: ""
        };

        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleChange(event) {
        this.setState({ [event.target.id]: event.target.value });
    }

    handleSubmit(event) {
        event.preventDefault();
        const { title } = this.state;
        const id = uuidv1();
        this.props.addArticle({ title, id });
        this.setState({ title: "" });
    }

    render() {
        const { title } = this.state;
        return (
            <form onSubmit={this.handleSubmit}>
                <div className="form-group">
                    <label htmlFor="title">Title</label>
                    <input
                        type="text"
                        className="form-control"
                        id="title"
                        value={title}
                        onChange={this.handleChange}
                    />
                </div>
                <button type="submit" className="btn btn-success btn-lg">
                    SAVE
        </button>
            </form>
        );
    }
}

const Form = connect(null, mapDispatchToProps)(ConnectedForm);

ConnectedForm.propTypes = {
    addArticle: PropTypes.func.isRequired
};

export default Form;

Chốt hạ

Hy vọng với cách trình bày của mình, các bạn hình dung được tư tưởng của Redux, cách dùng Redux với React như thế nào.

Bài viết được repost from vhnam.github.ioopen in new window

Last Updated 10/26/2023, 11:16:13 PM