React Hook - sử dụng useState vs chỉ các biến


12

React Hook cung cấp cho chúng ta tùy chọn useState và tôi luôn thấy các so sánh giữa Hook và Class-State. Nhưng những gì về Hook và một số biến thông thường?

Ví dụ,

function Foo() {
    let a = 0;
    a = 1;
    return <div>{a}</div>;
}

Tôi đã không sử dụng Móc và nó sẽ cho tôi kết quả giống như:

function Foo() {
    const [a, setA] = useState(0);
    if (a != 1) setA(1); // to avoid infinite-loop
    return <div>{a}</div>;
}

Vậy sự khác biệt là gì? Sử dụng Móc thậm chí còn phức tạp hơn cho trường hợp đó ... Vậy tại sao bắt đầu sử dụng nó?


Bạn đang so sánh 2 điều khác nhau mặc dù. Chức năng thứ hai với hook có khả năng cập nhật dữ liệu. Người đầu tiên không thực sự làm gì cả. Bạn có thể vừa khởi tạo nó let a = 1; return <div>{a}</div>và bạn sẽ nhận được kết quả tương tự.
Yathi

Câu trả lời:


13

Lý do là nếu bạn quay useStatelại xem. Các biến chỉ tự thay đổi bit trong bộ nhớ và trạng thái của ứng dụng của bạn có thể không đồng bộ với chế độ xem.

So sánh ví dụ này:

function Foo() {
    const [a, setA] = useState(0);
    return <div onClick={() => setA(a + 1)}>{a}</div>;
}

function Foo() {
    let a = 0;
    return <div onClick={() => a + 1}>{a}</div>;
}

Trong cả hai trường hợp, athay đổi khi nhấp nhưng chỉ khi bạn sử dụng useStatechế độ xem hiển thị chính xác agiá trị hiện tại.


Cảm ơn! Vì vậy, nếu tôi không cần hiển thị chế độ xem - chỉ là một cách để sắp xếp dữ liệu (đạo cụ) của tôi thành một số mảng - tôi có thể sử dụng 'let' không? Nó hoạt động với tôi, tôi chỉ muốn biết nó ổn và chấp nhận được.
Moshe Nagar

@MosheNagar nếu bạn lấy dữ liệu của mình từ các đạo cụ, bạn nên sử dụng các biến cục bộ thay vì giữ dữ liệu ở trạng thái vì thành phần sẽ quay lại thay đổi prop vì vậy chế độ xem sẽ đồng bộ với dữ liệu. Đặt chúng ở trạng thái sẽ chỉ gây ra sự tái xuất hiện không cần thiết - đầu tiên là thay đổi prop, sau đó là thay đổi trạng thái.
marzelin

Một cách khác để xem câu trả lời này là nghĩ rằng trong trường hợp thứ hai, biến asẽ là rác được thu thập sau khi hoàn thành việc thực thi, trong khi ở câu đầu tiên, vì nó tận dụng useStategiá trị củaa
João Marcos Gris

Anh ta vẫn có thể sử dụng useRefnếu anh ta không muốn hiển thị lại chế độ xem. Câu hỏi vẫn còn nếu anh ta nên sử dụng các biến cục bộ hoặc tham chiếu React. Ví dụ: nếu bạn có thời gian chờ bạn cần xóa hoặc yêu cầu http đang thực hiện bằng cách sử dụng axios, bạn có lưu trữ nguồn thời gian chờ hoặc axios trong một biến hoặc trong Reft ref không?
Tom

3
@Tom Quy tắc chung là sử dụng các vars cục bộ cho trạng thái dẫn xuất. Đối với bất cứ điều gì khác sử dụng useRef(nếu bạn không muốn đăng ký lại) hoặc useState(nếu bạn muốn đăng ký lại). Trong trường hợp bộ tính giờ, vì chúng là tác dụng phụ, chúng nên được bắt đầu trong useEffecthook. Nếu bạn timerIdchỉ muốn cho mục đích dọn dẹp, bạn có thể giữ nó trong biến cục bộ của trình xử lý . Nếu bạn muốn có thể xóa bộ đếm thời gian từ nơi khác trong thành phần, bạn nên sử dụng useRef. Lưu trữ timerIdtrong biến cục bộ của một thành phần sẽ là một sai lầm vì các vars cục bộ được "thiết lập lại" trên mỗi kết xuất.
marzelin

1

Cập nhật trạng thái sẽ làm cho thành phần hiển thị lại, nhưng giá trị cục bộ thì không.

Trong trường hợp của bạn, bạn đưa ra giá trị đó trong thành phần của bạn. Điều đó có nghĩa là, khi giá trị được thay đổi, thành phần sẽ được kết xuất lại để hiển thị giá trị được cập nhật.

Vì vậy, nó sẽ tốt hơn để sử dụng useStatehơn giá trị địa phương bình thường.

function Foo() {
    let a = 0;
    a = 1; // there will be no re-render.
    return <div>{a}</div>;
}

function Foo() {
    const [a, setA] = useState(0);
    if (a != 1) setA(1); // re-render required
    return <div>{a}</div>;
}

0

Ví dụ đầu tiên của bạn chỉ hoạt động vì về cơ bản dữ liệu không bao giờ thay đổi. Điểm nhập của việc sử dụng setStatelà để chạy lại toàn bộ thành phần của bạn khi trạng thái treo. Vì vậy, nếu ví dụ của bạn yêu cầu một số loại thay đổi hoặc quản lý trạng thái, bạn sẽ nhanh chóng nhận ra các giá trị thay đổi sẽ là cần thiết và để cập nhật chế độ xem với giá trị biến, bạn sẽ cần trạng thái và đăng ký lại.


0
function Foo() {
    const [a, setA] = useState(0);
    if (a != 1) setA(1); // to avoid infinite-loop
    return <div>{a}</div>;
}

tương đương với

class Foo extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            a: 0
        };
    }
    // ...
}

Những gì useStatetrả về là hai điều:

  1. biến trạng thái mới
  2. setter cho biến đó

nếu bạn gọi, setA(1)bạn sẽ gọi this.setState({ a: 1 })và kích hoạt kết xuất lại.


0

Các biến cục bộ sẽ được thiết lập lại mỗi lần hiển thị khi đột biến trong khi trạng thái sẽ cập nhật:

function App() {
  let a = 0; // reset to 0 on render/re-render
  const [b, setB] = useState(0);

  return (
    <div className="App">
      <div>
        {a}
        <button onClick={() => a++}>local variable a++</button>
      </div>
      <div>
        {b}
        <button onClick={() => setB(prevB => prevB + 1)}>
          state variable b++
        </button>
      </div>
    </div>
  );
}

Chỉnh sửa serene-galileo-ml3f0

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.