State trong ReactJS là gì? State là một đối tượng React tích hợp được sử dụng để chứa data hoặc thông tin về Component. State của một component có thể thay đổi theo thời gian; bất cứ khi nào nó thay đổi, component sẽ hiển thị lại.
Basic State
Các thành phần State in React rất cần thiết để quản lý và giao tiếp dữ liệu trong ứng dụng của bạn. Nó được biểu diễn dưới dạng một đối tượng JavaScript và có phạm vi cấp thành phần , nó có thể được coi là dữ liệu riêng tư của component của bạn.
Các bài viết liên quan:
Trong ví dụ dưới đây chúng ta định nghĩa một số trạng thái ban đầu trong constructor của các component và tận dụng nó trong render function
class ExampleComponent extends React.Component { constructor(props){ super(props); // thiết lập trạng thái ban đầu this.state = { greeting: 'Hiya Buddy!' }; } render() { // chúng ta có thể truy cập hệ thống bằng this.state return( <div>{this.state.greeting}</div> ); }
- Common Antipattern
Chúng ta không nên lưu props trong state. Nó được coi là 1 anti-pattern. Ví dụ:
export default class MyComponent extends React.Component { constructor() { super(); this.state = { url: '' } this.onChange = this.onChange.bind(this); } onChange(e) { this.setState({ url: this.props.url + '/days=?' + e.target.value }); } componentWillMount() { this.setState({url: this.props.url}); } render() { return ( <div> <input defaultValue={2} onChange={this.onChange} /> URL: {this.state.url} </div> ) } }
Prop url được lưu trong state và sau đó được sửa đổi. Thay vào đó, hãy lựa chọn lưu các thay đổi cho state và xây dựng đường dẫn đầy đủ bằng cách sử dụng state và props:
export default class MyComponent extends React.Component { constructor() { super(); this.state = { days: '' } this.onChange = this.onChange.bind(this); } onChange(e) { this.setState({ days: e.target.value }); } render() { return ( <div> <input defaultValue={2} onChange={this.onChange} /> URL: {this.props.url + '/days?=' + this.state.days} </div> ) } }
Điều này là do trong một ứng dụng React, chúng ta muốn có một source duy nhất – tức là tất cả dữ liệu thuộc trách nhiệm của một component duy nhất và chỉ một component. Component này có trách nhiệm lưu trữ dữ liệu trong state của nó và phân phối dữ liệu đến các components khác thông qua props.
Trong ví dụ đầu tiên, cả class MyComponent và lớp cha của nó đều đang duy trì ‘url’ trong state của chúng. Nếu chúng ta cập nhật state.url trong MyComponent, những thay đổi này sẽ không được phản ánh trong trang gốc. Chúng ta đã đánh mất source duy nhất của mình và ngày càng khó theo dõi luồng dữ liệu thông qua ứng dụng. Đối chiếu điều này với ví dụ thứ hai – url chỉ được duy trì ở trạng thái của parent component và được sử dụng làm prop trong MyComponent – do đó chúng tôi duy trì một source duy nhất.
- setState()
Cách chính để bạn thực hiện cập nhật giao diện người dùng cho các ứng dụng React của mình là thông qua lệnh gọi hàm setState () . Hàm này sẽ thực hiện shallow merge giữa trạng thái mới mà bạn cung cấp và trạng thái trước đó, đồng thời sẽ kích hoạt re-render của component và tất cả các decedents.
Thông số
- updater : Nó có thể là một đối tượng có một số cặp khóa-giá trị cần được hợp nhất vào trạng thái hoặc một hàm trả về một đối tượng.
- callback ( tùy chọn ) : một hàm sẽ được thực thi sau khi setState () được thực thi thành công. Thực tế là các lệnh gọi setState () không được React đảm bảo là nguyên tử, điều này đôi khi có thể hữu ích nếu bạn muốn thực hiện một số hành động sau khi khẳng định rằng setState () đã được thực thi thành công.
Sử dụng:
Phương thức setState chấp nhận 1 đối số của trình cập nhật, có thể có 1 đối tượng có 1 số cặp khóa- giá trị cần được hợp nhất vào trạng thái, hoặc 1 hàm trả về một đối tượng, như vậy tính từ prevState và props
- Using setState() với Object as updater
// ví dụ về ES6 style component, cập nhật trạng thái chỉ bằng 1 lần nhấp vào button// đồng thời chứng minh nơi có thể đặt state trực tiếp và nới setState nên được sử dụng. // class Greeting extends React.Component { constructor(props) { super(props); this.click = this.click.bind(this); // đặt trạng thái ban đầu (chỉ được cấp phép trong CONSTRUCTOR) this.state = { greeting: 'Hello!' }; } click(e) { this.setState({ greeting: 'Hello World!' }); } render() { return( <div> <p>{this.state.greeting}</p> <button onClick={this.click}>Click me</button> </div> ); } }
- Using setState() với Function as updater
// điều này thường được sử dụng nhất khi bạn muốn kiểm tra hoặc sử dụng
// trạng thái trước khi cập nhật.
// // điều này thường được sử dụng nhất khi bạn muốn kiểm tra hoặc sử dụng // trạng thái trước khi cập nhật. // this.setState(function(previousState, currentProps) { return { counter: previousState.counter + 1 }; });
Điều này có thể an toàn hơn so với việc sử dụng một đối số đối tượng trong đó nhiều lệnh gọi đến setState () để sử dụng, vì nhiều lệnh gọi có thể được React ghép nối với nhau và được thực thi cùng một lúc và là cách tiếp cận được ưa thích khi sử dụng các props hiện tại để thiết lập trạng thái.
this.setState({ counter: this.state.counter + 1 }); this.setState({ counter: this.state.counter + 1 }); this.setState({ counter: this.state.counter + 1 });
Các lệnh gọi này có thể được React kết hợp với nhau bằng Object.assign(), dẫn đến bộ đếm được tăng lên 1 thay vì 3.
Cách tiếp cận chức năng cũng có thể được sử dụng để di chuyển logic thiết lập trạng thái ra bên ngoài các components. Điều này cho phép cô lập và sử dụng lại logic trạng thái.
// bên ngoài lớp component, có khả năng nằm trong file/module khác function incrementCounter(previousState, currentProps) { return { counter: previousState.counter + 1 }; } //Ở trong component this.setState(incrementCounter); Calling setState() with an Object and a callback function // // 'Hi There' sẽ được đăng nhập vào bảng điều khiển sau khi setState hoàn tất // this.setState({ name: 'John Doe' }, console.log('Hi there'));
- State, Events và Managed Controls
Đây là một ví dụ về thành phần React với trường đầu vào “được quản lý”. Bất cứ khi nào giá trị của trường đầu vào thay đổi, một trình xử lý sự kiện được gọi để cập nhật trạng thái của component với giá trị mới của trường đầu vào. Lệnh gọi setState trong trình xử lý sự kiện sẽ kích hoạt lệnh gọi để render cập nhật component trong dom.
import React from 'react'; import {render} from 'react-dom'; class ManagedControlDemo extends React.Component { constructor(props){ super(props); this.state = {message: ""}; } handleChange(e){ this.setState({message: e.target.value}); } render() { return ( <div> <legend>Type something here</legend> <input onChange={this.handleChange.bind(this)} value={this.state.message} autoFocus /> <h1>{this.state.message}</h1> </div> ); } } render(<ManagedControlDemo/>, document.querySelector('#app'));
Điều rất quan trọng cần lưu ý là hành vi thời gian chạy. Mỗi khi người dùng thay đổi giá trị trong trường đầu vào handleChange sẽ được gọi và như vậy
- setState sẽ được gọi và như vậy
- render sẽ được gọi