Khước từ
Nested State trong React là thiết kế sai
Đọc câu trả lời tuyệt vời này .
Lý do đằng sau câu trả lời này:
SetState của React chỉ là một tiện ích tích hợp, nhưng bạn sẽ sớm nhận ra rằng nó có giới hạn của nó. Sử dụng các thuộc tính tùy chỉnh và sử dụng thông minh của ForceUpdate mang lại cho bạn nhiều hơn nữa. ví dụ:
class MyClass extends React.Component {
myState = someObject
inputValue = 42
...
MobX, ví dụ, bỏ hoàn toàn trạng thái và sử dụng các thuộc tính có thể quan sát tùy chỉnh.
Sử dụng Observables thay vì trạng thái trong các thành phần React.
câu trả lời cho sự khốn khổ của bạn - xem ví dụ ở đây
Có một cách khác ngắn hơn để cập nhật bất cứ tài sản lồng nhau nào.
this.setState(state => {
state.nested.flag = false
state.another.deep.prop = true
return state
})
Trên một dòng
this.setState(state => (state.nested.flag = false, state))
lưu ý: Đây là toán tử dấu phẩy ~ MDN , xem nó hoạt động ở đây (Hộp cát) .
Nó tương tự như (mặc dù điều này không thay đổi tham chiếu trạng thái)
this.state.nested.flag = false
this.forceUpdate()
Đối với sự khác biệt tinh tế trong bối cảnh này giữa forceUpdate
và setState
xem ví dụ được liên kết.
Tất nhiên điều này là lạm dụng một số nguyên tắc cốt lõi, vì state
chỉ nên đọc, nhưng vì bạn ngay lập tức loại bỏ trạng thái cũ và thay thế nó bằng trạng thái mới, nó hoàn toàn ổn.
Cảnh báo
Mặc dù thành phần có chứa trạng thái sẽ cập nhật và đăng ký lại đúng cách ( ngoại trừ gotcha này ) , các đạo cụ sẽ không truyền được cho trẻ em (xem bình luận của Spymaster bên dưới) . Chỉ sử dụng kỹ thuật này nếu bạn biết những gì bạn đang làm.
Ví dụ, bạn có thể vượt qua một chỗ dựa phẳng thay đổi được cập nhật và vượt qua dễ dàng.
render(
//some complex render with your nested state
<ChildComponent complexNestedProp={this.state.nested} pleaseRerender={Math.random()}/>
)
Bây giờ mặc dù tham chiếu cho ComplexNestedProp không thay đổi ( ShouldComponentUpdate )
this.props.complexNestedProp === nextProps.complexNestedProp
thành phần sẽ chạy lại bất cứ khi nào cập nhật thành phần cha mẹ, đó là trường hợp sau khi gọi this.setState
hoặc this.forceUpdate
trong cha mẹ.
Ảnh hưởng của đột biến nhà nước
Sử dụng nhà nước lồng nhau và biến đổi trạng thái trực tiếp rất nguy hiểm vì đối tượng khác nhau có thể giữ (cố ý hay không) (cũ) tài liệu tham khảo khác nhau đối với nhà nước và có thể không nhất thiết phải biết khi nào nên cập nhật (ví dụ như khi sử dụng PureComponent
hoặc nếu shouldComponentUpdate
được thực hiện để trả lại false
) HOẶC là dự định hiển thị dữ liệu cũ như trong ví dụ dưới đây.
Tưởng tượng một dòng thời gian được cho là hiển thị dữ liệu lịch sử, việc thay đổi dữ liệu dưới tay sẽ dẫn đến hành vi không mong muốn vì nó cũng sẽ thay đổi các mục trước đó.
Dù sao ở đây bạn có thể thấy rằng Nested PureChildClass
nó không được đăng ký lại do đạo cụ không truyền bá.