ReactJS

Context API in ReactJS

Context API in ReactJS

Dòng đời đưa đẩy, hồi này mình lại code React (^^). Dự án hiện tại cũng không dùng công nghệ gì cao siêu lắm, toàn dùng thuần. Mà cụ thể ở đây là không dùng Redux mà lại dùng Context để quản lí State giữa các phần với nhau, nên hôm này mình sẽ viết về cái này nhé.

1. Mở đầu

Nếu các bạn có làm việc với các Framework được dùng nhiều hiện giờ như VueJS, ReactJS, Angular2+, thì chắc cũng phải truyền data giữa các Component với nhau. Từ cha xuống con, hay emit data từ con nên cha, tuy nhiên khi nó có thể truyền qua một Component hoặc nhiều Component trung gian hay các Component không hề có mới quan hệ với nhau thì thật là thảm họa. Từ đó, các thư viện quản lí State được ra đời như redux, mobx, VueX, ….

Và đối với React chúng ta có thể chọn Redux, MobX hoặc Context Hooks, đối với dự án nào nhỏ nhỏ hoặc bạn thích thử cái mới để apply vào dự án. Hoặc đơn giản như mình là đang Maintain con dự án trước (^^) – Nhưng dù sao thì cũng khá thú vị.

Ở phần này mình sẽ chỉ nói đến việc lưu data, lấy ra và thay đổi nó như thế nào trong Context còn việc kết hợp với middleware mình xin hẹn bài sau.

2. Chi tiết

Context Hooks là gì?

Context provides a way to pass data through the component tree without having to pass props down manually at every level.

https://reactjs.org/docs/context.html#gatsby-focus-wrapper

Theo như trên trang chủ của React viết là như vậy, ở đây chúng ta có thể hiểu là: Context là một cách để truyền data giữa các Component với nhau mà không cần thông qua việc truyền giữa các cấp bậc Component.

Tại sao cần Context Hooks?

Như khái niệm ở trên, nó để truyền data giữa các Component giúp code gọn gàng, sáng sủa hơn (^^).

Cách dùng vào dự án như thế nào?

Đầu tiên các bạn hãy tạo cho mình Project trống nhé:

npx create-react-app context

Hoặc nếu có Project rồi thì bắt đầu thôi ^^.

Chú ý là ở đây mình sẽ giới thiệu đến bạn Context nhưng apply kiểu Redux vào nhé ^^, nếu bạn làm redux rồi sẽ thấy gần gũi hơn. Nhưng nếu chưa quen mình cũng sẽ nói sao cho dễ hiểu nhất nhé.

Đầu tiên bạn hãy tạo ra 3 Component bên trong {root}/components, mục đích chính là để Show data và để gắn một số Action vào nhé. Code tương tự cho Component như sau:

import React from 'react';

function Component() {
  return (
    <div>
      Component
      <hr />
    </div>
  );
}

export default Component;

Tiếp theo hãy tạo ra các Context bên trong {root}/contexts, ở đây là code mẫu:

export const CHANGE_TITLE = "CHANGE_TITLE";
export const DELETE_TITLE = "DELETE_TITLE";

Như bạn đã thấy đây là code phần constant, nó là Type mà sau này reducers sẽ nhận được.

import {
  CHANGE_TITLE,
  DELETE_TITLE
} from "./constants";

export const changeTitle = payload => ({
  type: CHANGE_TITLE,
  payload
});

export const deleteTitle = () => ({
  type: DELETE_TITLE
});

Đây là phần định nghĩa Actions, những function callback mà su này được gọi để gửi đến Reducer từ đó thay đổi State.

import {
  CHANGE_TITLE,
  DELETE_TITLE,
} from "./constants";

export const reducer = (state, action) => {
  switch (action.type) {
    case CHANGE_TITLE:
      return {title: action.payload};
    case DELETE_TITLE:
      return {title: ''};
    default:
      break;
  };
};

Đây là phần Reducer nơi mà nhận action nào đi với case nào từ đó thay đổi State.

import React, { useReducer } from 'react';
import { reducer } from './reducer';
import {
  changeTitle,
  deleteTitle
} from './actions';

export const TitleContext = React.createContext();

const initState = {
  title: "This is default title."
};

export function TitleProvider(props) {
  const [state, dispatch] = useReducer(reducer, initState);
  const value = { state, dispatch };

  return (
    <TitleContext.Provider
      value={value}
    >
        {props.children}
    </TitleContext.Provider>
  );
};

export {
  changeTitle,
  deleteTitle
}

Đây có lẽ là phần mà bạn cần lưu tâm nhiều nhất, ở đây chúng ta sẽ CreateContext, nếu bạn đọc trong một số phần họ sẽ Init value ở đây luôn. Nhưng với mình, mình dùng Reducer (lại 1 cái hook nữa), nên mình CreateContext chỉ đơn giản là dùng Provider của nó thôi. Còn việc init State thì dành cho Reducer. Còn dispatch là function để truyền data mà về sau khi dùng mình sẽ call đến actions (Đã khai báo bên trên). Ở đây bạn để ý là mình có Import và export Actions, mục đích chính là cho nó gọn gàng thôi nhé. Còn children chính là component mà dùng Context này, bạn phải truyền chúng bên trong Provider.

Sau đó khi đã xong rồi bạn có thể Wrap các Component A, B, C vào bên trong Provider đã export này. Tuy nhiên (Lại tuy nhiên ^^), nếu có nhiều Provider vì sẽ nested rất nhiều. Provider nồng Provider, … như vậy thì không hay một chút nào.

<Provider_1>
  <Provider_2>
    <Provider_3>
      <Provider_4>
        <Provider_5>

          <Component_1 />
          <Component_2 />
          ...

        </Provider_5>
      </Provider_4>
    </Provider_3>
  </Provider_2>
</Provider_1>

Nên mình đã tham khảo và Implement 1 Wrap Provider bạn có thể tham khảo nhé:

import React from 'react';
import { CountProvider } from './count-context';
import { TitleProvider } from './title-context';

export function StoreProvider(props) {
  return (
    <>
      {[CountProvider, TitleProvider].reduce((ProviderNested, ProviderCurrent) => {
        return <ProviderCurrent>{ProviderNested}</ProviderCurrent>
      }, props.children)}
    </>
  );
}

export default StoreProvider;

Như vây, nếu bạn có nhiề Provider thì cũng không cần sợ nữa nhé, sau khi có Function bên trên Code của chúng ra sẽ trông như thế này:

<StoreProvider>
  <Component_1 />
  <Component_1 />
  ...
</StoreProvider>

Mình nghĩ có lẽ bạn chưa hiểu nhiều, nên mình đã code rất chi tiết ở ví dụ bên dưới rồi nhé, bạn nên lấy về Run và chạy xem sao nhé. Nếu bạn thấy hữu ích thì hãy cho mình 1 sao nhé. Thanks bạn nhiều.

Mình có để ví dụ của mình ở đây bạn có thể tham khảo nếu cần nhé.

3. Kết luận

Như các bạn đã thấy đó, việc dùng Context vào dự án là không hề khó, không hề phức tạp mà lại còn đỡ phải import thêm thư viện vì React nó có sẵn cho chúng ta cả rồi, thật là tiện.

Tuy nhiên khi dự án to to, hoặc business phức tạp thì mình vẫn suggest là nên dùng Redux vì kiểu gì bạn cũng dễ debbug hơn, Redux nó có Extension riêng. Vậy nên bạn nên cân nhắc trước khi dùng nhé, mục đích vẫn là business hoạt động trơn tru, ít BUG.

4. Tham khảo

# Context
# React (web framework)
# Working with the React Context API

Tagged , , , ,
0 0 vote
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments