useContext in React

min read

Day 39/100 #100DaysOfCode #React #ReactNative

Nay mình đi tìm hiểu useContext trong React, vừa qua mình có tìm hiểu sơ qua về useContext, giúp ta gửi dữ liệu xuống các component, component nào cần dùng thì chỉ cần gọi useContext là có thể sử dụng được.

Thông thường ta hay sử dụng redux để lưu state trong Store, bên cạnh đó nếu mô hình nhỏ, dự án nhỏ , lưu state không nhiều thì ta có thể dùng useContext để xử lý vấn đề.

Để sử dụng được useContext() ta cần khởi tạo cú pháp như sau:

const ExampleContext = React.createContext();

Ta có thể chèn dữ liệu default cho useContext cũng được: 

const ExampleContext = React.createContext("data default");

Okay, mình làm một ví dụ sơ qua về useContext như sau:

+ Tạo file UseContext.js

import React from 'react'
export const ExampleContext = React.createContext();

+ Tạo file ProductComponent.js

import React from 'react'
import TitleComponent from './TitleComponent';
import {ExampleContext} from './UseContext';
function ProductComponent() {
  return (
    <>
        <h1>ProductComponent</h1>
        <ExampleContext.Provider value={{ title: 'Iphone 13 Pro Max' }}>
            <div className='use-context'>
                <TitleComponent />
            </div>
        </ExampleContext.Provider>
    </>
  )
}

export default ProductComponent

Bên trên ta cần gọi ExampleContext vào ProductComponent, sau đó sử dụng Provider để chứa giá trị và pass nó xuống các children component bên dưới

<ExampleContext.Provider value={{ title: 'Iphone 13 Pro Max' }}>
            <div className='use-context'>
                <TitleComponent />
            </div>
 </ExampleContext.Provider>

+ Tạo file component TitleComponent.js như sau:

import React from 'react'
import {ExampleContext} from './UseContext'
function TitleComponent() {
    const { title } = React.useContext(ExampleContext);
  return (
    <div>
      <span>Title: {title}</span>
      <ExampleContext.Consumer>
        {value => <h2>{value.title}</h2>}
      </ExampleContext.Consumer>
    </div>

  )
}

export default TitleComponent

Bên trên mình có 2 cách để nhận giá trị từ useContext nghe:

+ Cách 1: sử dụng useContext() để nhận giá trị

const { title } = React.useContext(ExampleContext);
<span>Title: {title}</span>

+ Cách 2: sử dụng Consumer hứng giá trị từ Provider , để hiện thị ra thôi

<ExampleContext.Consumer>
    {value => <h2>{value.title}</h2>}
</ExampleContext.Consumer>

Bên trên là cách mà bạn có thể sử dụng useContext, giờ mình sẽ tối ưu nó nhìn gọn hơn xíu như sau, bạn có thể làm theo nhé:

+ File UseContext.js

import React,{useState} from 'react'
export const MContext = React.createContext();
const MyProvider = (props)=>{
    const [state, setState] = useState({ message: "title default" });

    return(
        <MContext.Provider
        value={{
          state: state,
          setMessage: (value) =>
            setState({
              message: value
            })
        }}
      >
        {props.children}
      </MContext.Provider>
    )
}
export default MyProvider;

+ File ProductComponent.js

import React,{useContext} from 'react'
import MyProvider from './UseContext';
import TitleComponent from './TitleComponent'
function ProductComponent() {
  
  return (
    <>
        <h1>Product Component</h1>
        <MyProvider>
            <TitleComponent />
        </MyProvider>
    </>
  )
}

export default ProductComponent

+ File TitleComponent.js

import React,{useContext} from 'react'
import {MContext} from './UseContext';

function TitleComponent() {
  const {state} = useContext(MContext);
  console.log(state.message)
  return (
    <div>
      <span>Title:  {state.message}</span>
      <MContext.Consumer>
        {(context) => (
          <div>
            <p>{context.state.message}</p>
            <button
              onClick={() => {
                context.setMessage("New Arrival 6");
              }}
            >
              Send
            </button>
            <input
              type="text"
              onChange={(e) => context.setMessage(e.target.value)}
            />
          </div>
        )}
      </MContext.Consumer>
    </div>

  )
}

export default TitleComponent

Trong component TitleComponent ta dùng Comsumer để hứng giá trị từ Provider và show ra thôi, bên cạnh đó ta có cấu hình một cái function setMessage để cập nhật giá trị, hoặc bạn có thể dùng useReducer + useContext để quản lý state , bạn  pass  (state, dispath) vào provider, thì các children component có thể dispath một action đến useReducer.

Tuy thuộc vào vấn đề mà ta xử lý thôi, nếu vấn đề nhỏ thì ta có thể dùng useContext , còn phức tạp quá mình khuyên là nên sử dụng redux, để xử lý nhiều vấn đề, bạn có thể xem ví dụ mẫu về redux link sau:

CREATE A SIMPLE REACT WITH REDUX

BUILD A SHOPPING CART WITH REACT + REDUX

x

Ủng hộ tôi bằng cách click vào quảng cáo. Để tôi có kinh phí tiếp tục phát triển Website!(Support me by clicking on the ad. Let me have the money to continue developing the Website!)