/ / Cách quản lý hiệu quả trạng thái trong React

Cách quản lý hiệu quả trạng thái trong React

woman working in acer computer

Nếu bạn đã viết rất nhiều mã React, rất có thể bạn đã sử dụng sai trạng thái. Một sai lầm phổ biến mà nhiều nhà phát triển React mắc phải là lưu trữ các trạng thái trên toàn cầu trong ứng dụng, thay vì lưu trữ chúng trong các thành phần nơi chúng được sử dụng.


Tìm hiểu cách bạn có thể cấu trúc lại mã của mình để sử dụng trạng thái cục bộ và tại sao làm như vậy luôn là một ý tưởng hay.


Ví dụ cơ bản về State trong React

Đây là một ứng dụng truy cập rất đơn giản minh họa cách trạng thái thường được xử lý trong React:

 import {useState} from 'react'
import {Counter} from 'counter'

function App(){
  const [count, setCount] = useState(0)
  return <Counter count={count} setCount={setCount} />
}

export default App

Trên dòng 1 và 2, bạn nhập useState() hook để tạo trạng thái và Quầy tính tiền thành phần. Bạn xác định đếm nhà nước và đặtCount Phương thức cập nhật trạng thái Sau đó, bạn chuyển cả hai xuống Quầy tính tiền thành phần.

Các Quầy tính tiền thành phần sau đó kết xuất đếm và cuộc gọi đặtCount để tăng và giảm số đếm.

 function Counter({count, setCount}) {
  return (
    <div>
      <button onClick={() => setCount(prev => prev - 1)}>-</button>
      <span>{count}</span>
      <button onClick={() => setCount(prev => prev + 1)}>+</button>
    </div>
  )
}

Bạn đã không xác định đếm biến và đặtCount hoạt động cục bộ bên trong Quầy tính tiền thành phần. Thay vào đó, bạn đã chuyển nó từ thành phần cha (Ứng dụng). Nói cách khác, bạn đang sử dụng trạng thái toàn cầu.

Vấn đề với các quốc gia toàn cầu

Vấn đề với việc sử dụng trạng thái chung là bạn đang lưu trữ trạng thái trong thành phần cha (hoặc cha của cha mẹ) và sau đó chuyển nó xuống dưới dạng đạo cụ cho thành phần thực sự cần trạng thái đó.

Đôi khi điều này tốt khi bạn có một trạng thái được chia sẻ trên nhiều thành phần. Nhưng trong trường hợp này, không có thành phần nào khác quan tâm đến đếm nhà nước ngoại trừ Quầy tính tiền thành phần. Do đó, tốt hơn là chuyển trạng thái sang Quầy tính tiền thành phần nơi nó thực sự được sử dụng.

Chuyển State sang Child Component

Khi bạn chuyển trạng thái sang Quầy tính tiền thành phần, nó sẽ trông như thế này:

 import {useState} from 'react'

function Counter() {
  const [count, setCount] = useState(0)
  return (
    <div>
      <button onClick={() => setCount(prev => prev - 1)}>-</button>
      <span>{count}</span>
      <button onClick={() => setCount(prev => prev + 1)}>+</button>
    </div>
  )
}

Sau đó, bên trong của bạn Ứng dụng thành phần, bạn không cần phải chuyển bất cứ thứ gì xuống Quầy tính tiền thành phần:

 
function App(){
  return <Counter />
}

Bộ đếm sẽ hoạt động chính xác như trước đây, nhưng điểm khác biệt lớn là tất cả các trạng thái của bạn đều nằm cục bộ bên trong bộ đếm này. Quầy tính tiền thành phần. Vì vậy, nếu bạn cần có một bộ đếm khác trên trang chủ, thì bạn sẽ có hai bộ đếm độc lập. Mỗi quầy đều khép kín và đảm nhận tất cả trạng thái của chính nó.

Xử lý trạng thái trong các ứng dụng phức tạp hơn

Một tình huống khác mà bạn muốn sử dụng trạng thái chung là với các biểu mẫu. Các Ứng dụng thành phần bên dưới chuyển dữ liệu biểu mẫu (email và mật khẩu) và phương thức setter xuống Mẫu đăng nhập thành phần.

 import { useState } from "react";
import { LoginForm } from "./LoginForm";

function App() {
  const [formData, setFormData] = useState({
     email: "",
     password: "",
  });

 function updateFormData(newData) {
    setFormData((prev) => {
      return { ...prev, ...newData };
    });
  }

 function onSubmit() {
    console.log(formData);
  }

 return (
    <LoginForm
      data={formData}
      updateData={updateFormData}
      onSubmit={onSubmit}
    />
  );
}

Các Mẫu đăng nhập thành phần lấy thông tin đăng nhập và hiển thị nó. Khi bạn gửi biểu mẫu, nó sẽ gọi cập nhật dữ liệu chức năng cũng được truyền xuống từ thành phần cha mẹ.

 function LoginForm({ onSubmit, data, updateData }) {
  function handleSubmit(e) {
    e.preventDefault();
    onSubmit();
  }

  return (
    <form onSubmit={handleSubmit}>
      <label htmlFor="email">Email</label>
      <input
        type="email"
        id="email"
        value={data.email}
        onChange={(e) => updateData({ email: e.target.value })}
      />
      <label htmlFor="password">Password</label>
      <input
        type="password"
        id="password"
        value={data.password}
        onChange={(e) => updateData({ password: e.target.value })}
      />
      <button type="submit">Submit</button>
    </form>
  );
}

Thay vì quản lý trạng thái trên thành phần chính, tốt hơn là chuyển trạng thái sang LoginForm.js, đó là nơi bạn sẽ sử dụng mã. Làm như vậy làm cho mỗi thành phần độc lập và không phụ thuộc vào thành phần khác (tức là cha mẹ) để lấy dữ liệu. Đây là phiên bản sửa đổi của Mẫu đăng nhập:

 import { useRef } from "react";

function LoginForm({ onSubmit }) {
  const emailRef = useRef();
  const passwordRef = useRef();
  
 function handleSubmit(e) {
    e.preventDefault();
    onSubmit({
      email: emailRef.current.value,
      password: passwordRef.current.value,
    });
  }

 return (
    <form onSubmit={handleSubmit}>
      <label htmlFor="email">Email</label>
      <input type="email" id="email" ref={emailRef} />
      <label htmlFor="password">Password</label>
      <input type="password" id="password" ref={passwordRef} />
      <button type="submit">Submit</button>
    </form>
  );
}

Tại đây, bạn liên kết đầu vào với một biến bằng cách sử dụng giới thiệu thuộc tính và sử dụngRef React hook, thay vì chuyển trực tiếp các phương thức cập nhật. Điều này giúp bạn loại bỏ mã dài dòng và tối ưu hóa hiệu suất của biểu mẫu bằng cách sử dụng hook useRef.

Trong thành phần cha mẹ (App.js), bạn có thể xóa cả trạng thái chung và cập nhậtFormData() bởi vì bạn không còn cần nó nữa. Chức năng duy nhất còn lại là onSubmit()mà bạn gọi từ bên trong Mẫu đăng nhập thành phần để ghi lại các chi tiết đăng nhập trên bảng điều khiển.

 function App() {
  function onSubmit(formData) {
    console.log(formData);
  }

 return (
    <LoginForm
      data={formData}
      updateData={updateFormData}
      onSubmit={onSubmit}
    />
  );
}

Bạn không chỉ biến trạng thái của mình thành cục bộ nhất có thể mà còn thực sự loại bỏ nhu cầu về bất kỳ trạng thái nào (và đã sử dụng giới thiệu thay vì). Vậy bạn Ứng dụng thành phần đã trở nên đơn giản hơn nhiều (chỉ có một chức năng).

Của bạn Mẫu đăng nhập thành phần cũng trở nên đơn giản hơn vì bạn không cần phải lo lắng về việc cập nhật trạng thái. Thay vào đó, bạn chỉ cần theo dõi hai giới thiệuvà đó là nó.

Xử lý trạng thái chia sẻ

Có một vấn đề với cách tiếp cận cố gắng làm cho trạng thái càng cục bộ càng tốt. Bạn thường gặp phải các tình huống trong đó thành phần chính không sử dụng trạng thái nhưng nó chuyển trạng thái đó cho nhiều thành phần.

Một ví dụ là có một TodoContainer thành phần cha mẹ với hai thành phần con: Những việc cần làmTodoCount.

 function TodoContainer() {
  const [todos, setTodos] = useState([])

  return (
    <>
      <TodoList todos={todos}>
      <TodoCount todos={todos}>
    </>
  )
}

Cả hai thành phần con này đều yêu cầu việc cần làm nhà nước, vì vậy TodoContainer chuyển nó cho cả hai người họ. Trong những trường hợp như thế này, bạn phải đặt trạng thái cục bộ nhất có thể. Trong ví dụ trên, đặt nó bên trong TodosContainer là địa phương như bạn có thể nhận được.

Nếu bạn đặt trạng thái này vào Ứng dụng thành phần, nó sẽ không cục bộ nhất có thể vì nó không phải là thành phần cha gần nhất với hai thành phần cần dữ liệu.

Đối với các ứng dụng lớn, việc quản lý trạng thái chỉ bằng useState() hook có thể chứng minh là khó khăn. Trong những trường hợp như vậy, bạn có thể cần chọn React Context API hoặc React Redux để quản lý trạng thái một cách hiệu quả.

Tìm hiểu thêm về React Hook

Hook tạo thành nền tảng của React. Bằng cách sử dụng các hook trong React, bạn có thể tránh viết mã dài mà nếu không sẽ sử dụng các lớp. UseState() hook rõ ràng là hook React được sử dụng phổ biến nhất, nhưng còn có nhiều hook khác như useEffect(), useRef() và useContext().

Nếu bạn đang muốn trở nên thành thạo trong việc phát triển ứng dụng với React, thì bạn cần biết cách sử dụng các hook này trong ứng dụng của mình.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *