UseState () trong React là gì?


134

Tôi hiện đang học khái niệm hooks trong React và cố gắng hiểu ví dụ dưới đây.

import { useState } from 'react';

function Example() {
    // Declare a new state variable, which we'll call "count"
    const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

Ví dụ trên tăng bộ đếm trên chính tham số hàm xử lý. Điều gì xảy ra nếu tôi muốn sửa đổi giá trị đếm bên trong hàm xử lý sự kiện

Hãy xem xét ví dụ dưới đây

setCount = () => {
  //how can I modify count value here. Not sure if I can use setState to modify its value
  //also I want to modify other state values as well here. How can I do that
}

<button onClick={() => setCount()}>
  Click me
</button>

Bạn cũng có thể xem mã nguồn để hiểu cách useStatetriển khai. Đây là định nghĩa của phiên bản 16.9 .
chemturion

Câu trả lời:


148

React hooks là một cách mới (vẫn đang được phát triển) để truy cập các tính năng cốt lõi của react chẳng hạn như statekhông cần phải sử dụng các lớp, trong ví dụ của bạn nếu bạn muốn tăng bộ đếm trực tiếp trong hàm xử lý mà không cần chỉ định nó trực tiếp trong phần onClickhỗ trợ, bạn có thể làm điều gì đó như:

...
const [count, setCounter] = useState(0);
const [moreStuff, setMoreStuff] = useState(...);
...

const setCount = () => {
    setCounter(count + 1);
    setMoreStuff(...);
    ...
};

và onClick:

<button onClick={setCount}>
    Click me
</button>

Hãy nhanh chóng giải thích những gì đang xảy ra trong dòng này:

const [count, setCounter] = useState(0);

useState(0)trả về một bộ giá trị trong đó tham số đầu tiên countlà trạng thái hiện tại của bộ đếm và setCounterlà phương thức cho phép chúng ta cập nhật trạng thái của bộ đếm. Chúng ta có thể sử dụng setCounterphương thức để cập nhật trạng thái của countbất kỳ đâu - Trong trường hợp này, chúng ta đang sử dụng nó bên trong setCounthàm nơi chúng ta có thể làm nhiều việc hơn; ý tưởng với hook là chúng ta có thể giữ cho mã của mình nhiều chức năng hơn và tránh các thành phần dựa trên lớp nếu không muốn / cần thiết.

Tôi đã viết một bài viết đầy đủ về móc với nhiều ví dụ (bao gồm quầy) như này codepen , tôi đã sử dụng useState, useEffect, useContext, và móc tùy chỉnh . Tôi có thể tìm hiểu thêm chi tiết về cách hook hoạt động trên câu trả lời này nhưng tài liệu giải thích rất chi tiết về state hook và các hook khác, hy vọng nó sẽ hữu ích.

cập nhật: Hook không còn là một đề xuất nữa , kể từ phiên bản 16.8, chúng hiện có sẵn để sử dụng, có một phần trong trang web của React trả lời một số Câu hỏi thường gặp .


2
Tương tự tốt ngoại trừ việc JavaScript không có kiểu dữ liệu tuple về mặt kỹ thuật
goonerify

Chà, bài tập đã hủy được sử dụng giống như tuple stackoverflow.com/a/4513061/6335029
NaveenDA

Các móc có không đồng bộ không? Khi sử dụng setSomething, nếu sau đó tôi thử sử dụng somethingtrực tiếp sau đó, nó dường như vẫn có giá trị cũ ...
Byron Coetsee

51

useStatelà một trong những móc phản ứng tích hợp có sẵn trong 0.16.7phiên bản.

useStatechỉ nên được sử dụng bên trong các thành phần chức năng. useStatelà cách nếu chúng ta cần một trạng thái bên trong và không cần triển khai logic phức tạp hơn như các phương thức vòng đời.

const [state, setState] = useState(initialState);

Trả về một giá trị trạng thái và một hàm để cập nhật nó.

Trong lần hiển thị ban đầu, trạng thái (trạng thái) được trả về giống với giá trị được truyền như đối số đầu tiên (InitialState).

Hàm setState được sử dụng để cập nhật trạng thái. Nó chấp nhận một giá trị trạng thái mới và xếp hàng đợi kết xuất lại thành phần.

Xin lưu ý rằng useStatehook callback để cập nhật trạng thái hoạt động khác với các thành phần this.setState. Để cho bạn thấy sự khác biệt, tôi đã chuẩn bị hai ví dụ.

class UserInfoClass extends React.Component {
  state = { firstName: 'John', lastName: 'Doe' };
  
  render() {
    return <div>
      <p>userInfo: {JSON.stringify(this.state)}</p>
      <button onClick={() => this.setState({ 
        firstName: 'Jason'
      })}>Update name to Jason</button>
    </div>;
  }
}

// Please note that new object is created when setUserInfo callback is used
function UserInfoFunction() {
  const [userInfo, setUserInfo] = React.useState({ 
    firstName: 'John', lastName: 'Doe',
  });

  return (
    <div>
      <p>userInfo: {JSON.stringify(userInfo)}</p>
      <button onClick={() => setUserInfo({ firstName: 'Jason' })}>Update name to Jason</button>
    </div>
  );
}

ReactDOM.render(
  <div>
    <UserInfoClass />
    <UserInfoFunction />
  </div>
, document.querySelector('#app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>

<div id="app"></div>

Đối tượng mới được tạo khi setUserInfogọi lại được sử dụng. Lưu ý rằng chúng tôi đã mất lastNamegiá trị khóa. Để khắc phục điều đó, chúng ta có thể chuyển hàm vào bên trong useState.

setUserInfo(prevState => ({ ...prevState, firstName: 'Jason' })

Xem ví dụ:

// Please note that new object is created when setUserInfo callback is used
function UserInfoFunction() {
  const [userInfo, setUserInfo] = React.useState({ 
    firstName: 'John', lastName: 'Doe',
  });

  return (
    <div>
      <p>userInfo: {JSON.stringify(userInfo)}</p>
      <button onClick={() => setUserInfo(prevState => ({
        ...prevState, firstName: 'Jason' }))}>
        Update name to Jason
      </button>
    </div>
  );
}

ReactDOM.render(
    <UserInfoFunction />
, document.querySelector('#app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>

<div id="app"></div>

Không giống như phương thức setState được tìm thấy trong các thành phần lớp, useState không tự động hợp nhất các đối tượng cập nhật. Bạn có thể sao chép hành vi này bằng cách kết hợp biểu mẫu trình cập nhật chức năng với cú pháp lây lan đối tượng:

setState(prevState => {
  // Object.assign would also work
  return {...prevState, ...updatedValues};
});

Để biết thêm về useStatexem tài liệu chính thức .


2
Cảm ơn bạn đã thêm một hàm làm tham số trong ví dụ.
Juni Brosas

15

Cú pháp của useStatehook rất đơn giản.

const [value, setValue] = useState(defaultValue)

Nếu bạn không quen với cú pháp này, hãy truy cập vào đây .

Tôi khuyên bạn nên đọc tài liệu . Có những giải thích tuyệt vời với lượng ví dụ phong phú.

import { useState } from 'react';

function Example() {
    // Declare a new state variable, which we'll call "count"
    const [count, setCount] = useState(0);
  
  // its up to you how you do it
  const buttonClickHandler = e => {
   // increment
   // setCount(count + 1)
   
   // decrement
   // setCount(count -1)
   
   // anything
   // setCount(0)
  }
  

  return (
       <div>
          <p>You clicked {count} times</p>
         <button onClick={buttonClickHandler}>
             Click me
         </button>
      </div>
   );
 }


Đây phải là câu trả lời được chấp nhận. Ngắn gọn và rõ ràng, có tài liệu tham khảo bên ngoài tốt.
varun

8

useStatelà một trong những hook có sẵn trong React v16.8.0. Về cơ bản, nó cho phép bạn chuyển các thành phần không có trạng thái / chức năng khác của bạn thành một thành phần có thể có trạng thái riêng của nó.

Ở cấp độ rất cơ bản, nó được sử dụng theo cách này:

const [isLoading, setLoading] = useState(true);

Sau đó, điều này cho phép bạn setLoadingchuyển một giá trị boolean. Đó là một cách hay để có thành phần chức năng "trạng thái".


7

useState()là một React hook. Hooks có thể sử dụng trạng thái và khả năng thay đổi bên trong các thành phần chức năng.

Mặc dù bạn không thể sử dụng hook bên trong các lớp, nhưng bạn có thể bọc thành phần lớp của mình bằng một hàm một và sử dụng các hook từ nó. Đây là một công cụ tuyệt vời để di chuyển các thành phần từ lớp sang dạng hàm. Đây là một ví dụ đầy đủ:

Đối với ví dụ này, tôi sẽ sử dụng một thành phần bộ đếm. Đây là nó:

class Hello extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: props.count };
  }
  
  inc() {
    this.setState(prev => ({count: prev.count+1}));
  }
  
  render() {
    return <button onClick={() => this.inc()}>{this.state.count}</button>
  }
}

ReactDOM.render(<Hello count={0}/>, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root'></div>

Nó là một thành phần lớp đơn giản với trạng thái đếm và việc cập nhật trạng thái được thực hiện bằng các phương thức. Đây là mẫu rất phổ biến trong các thành phần lớp. Điều đầu tiên là bọc nó bằng một thành phần hàm có cùng tên, ủy nhiệm tất cả các thuộc tính của nó cho thành phần được bọc. Ngoài ra, bạn cần kết xuất thành phần được bao bọc trong hàm trả về. Nó đây:

function Hello(props) {
  class Hello extends React.Component {
    constructor(props) {
      super(props);
      this.state = { count: props.count };
    }

    inc() {
      this.setState(prev => ({count: prev.count+1}));
    }

    render() {
      return <button onClick={() => this.inc()}>{this.state.count}</button>
    }
  }
  return <Hello {...props}/>
}

ReactDOM.render(<Hello count={0}/>, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root'></div>

Đây chính xác là thành phần giống nhau, có cùng hành vi, cùng tên và cùng thuộc tính. Bây giờ hãy nâng trạng thái đếm lên thành phần hàm. Đây là cách nó thực hiện:

function Hello(props) {
  const [count, setCount] = React.useState(0);
  class Hello extends React.Component {
    constructor(props) {
      super(props);
      this.state = { count: props.count };
    }

    inc() {
      this.setState(prev => ({count: prev.count+1}));
    }

    render() {
      return <button onClick={() => setCount(count+1)}>{count}</button>
    }
  }
  return <Hello {...props}/>
}

ReactDOM.render(<Hello count={0}/>, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js" integrity="sha256-3vo65ZXn5pfsCfGM5H55X+SmwJHBlyNHPwRmWAPgJnM=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js" integrity="sha256-qVsF1ftL3vUq8RFOLwPnKimXOLo72xguDliIxeffHRc=" crossorigin="anonymous"></script>
<div id='root'></div>

Lưu ý rằng phương pháp incvẫn còn đó, nó sẽ không làm tổn thương bất kỳ ai, trên thực tế là mã chết. Đây là ý tưởng, chỉ cần tiếp tục nâng trạng thái lên. Sau khi hoàn thành, bạn có thể xóa thành phần lớp:

function Hello(props) {
  const [count, setCount] = React.useState(0);

  return <button onClick={() => setCount(count+1)}>{count}</button>;
}

ReactDOM.render(<Hello count={0}/>, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js" integrity="sha256-3vo65ZXn5pfsCfGM5H55X+SmwJHBlyNHPwRmWAPgJnM=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js" integrity="sha256-qVsF1ftL3vUq8RFOLwPnKimXOLo72xguDliIxeffHRc=" crossorigin="anonymous"></script>

<div id='root'></div>

Mặc dù điều này giúp bạn có thể sử dụng hook bên trong các thành phần lớp, nhưng tôi không khuyên bạn làm như vậy ngoại trừ trường hợp bạn di chuyển như tôi đã làm trong ví dụ này. Việc trộn lẫn các thành phần chức năng và lớp sẽ làm cho việc quản lý nhà nước trở nên lộn xộn. Tôi hi vọng cái này giúp được

Trân trọng


7

useState () là một ví dụ về React hook tích hợp sẵn cho phép bạn sử dụng các trạng thái trong các thành phần chức năng của mình. Điều này đã không thể xảy ra trước React 16.7.

Hàm useState là một hook tích hợp có thể được nhập từ gói react. Nó cho phép bạn thêm trạng thái vào các thành phần chức năng của mình. Sử dụng hook useState bên trong một thành phần hàm, bạn có thể tạo một phần trạng thái mà không cần chuyển sang các thành phần lớp.


5

Hooks là một tính năng mới trong React v16.7.0-alpha useState"Hook". useState()đặt giá trị mặc định của bất kỳ biến nào và quản lý trong thành phần hàm (các hàm PureComponent). ex : const [count, setCount] = useState(0);đặt giá trị mặc định của số đếm 0. và u có thể sử dụng setCountthành incrementhoặc decrementgiá trị. onClick={() => setCount(count + 1)}tăng giá trị đếm. DOC


5

Cảm ơn loelsonk, tôi đã làm như vậy

const [dataAction, setDataAction] = useState({name: '', description: ''});

    const _handleChangeName = (data) => {
        if(data.name)
            setDataAction( prevState  => ({ ...prevState,   name : data.name }));
        if(data.description)
            setDataAction( prevState  => ({ ...prevState,   description : data.description }));
    };
    
    ....return (
    
          <input onChange={(event) => _handleChangeName({name: event.target.value})}/>
          <input onChange={(event) => _handleChangeName({description: event.target.value})}/>
    )


2

useState là một hook cho phép bạn thêm trạng thái vào một thành phần chức năng. Nó chấp nhận một đối số là giá trị ban đầu của thuộc tính trạng thái và trả về giá trị hiện tại của thuộc tính trạng thái và một phương thức có khả năng cập nhật thuộc tính trạng thái đó.
Sau đây là một ví dụ đơn giản:
import React, {useState} from react
function HookCounter {
const [count, stateCount]= useState(0)
return(
<div>
<button onClick{( ) => setCount(count+1)}> count{count} </button>
</div>
)
}

useState chấp nhận giá trị ban đầu của biến trạng thái là 0 trong trường hợp này và trả về một cặp giá trị. Giá trị hiện tại của trạng thái được gọi là count và một phương thức có thể cập nhật biến trạng thái được gọi là setCount.

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.