Có một số great video về lợi ích và triển khai cho dữ liệu bất biến, từ bài nói chuyện của Lee tại React Conf 2015. Theo như suy nghĩ về dữ liệu không thể thay đổi và phản ứng, tôi xem xét xem cần thiết.
Điều đó sang một bên, dưới đây là một vài suy nghĩ của tôi về vấn đề này.
Mã người dùng
Trạng thái của bạn trở nên phức tạp, khó quản lý hơn với chữ và toán tử trải rộng. Hãy tưởng tượng rằng hơn là bằng phẳng, bạn đã có một vài mức độ của nhà nước lồng nhau:
const initialState = {
core: {
tracker: {
activeTrackId: '',
state: 'stopped'
}
}
};
Mặc dù nó vẫn có thể sử dụng toán tử lan rộng, nó bắt đầu trở nên tẻ nhạt.
return {
...state,
core: {
...state.core,
tracker: {
...state.core.tracker,
activeTrackId: action.state !== 'stopped' ? action.track._id : '',
state: action.state
}
}
};
Bây giờ hãy xem xét tương đương với Immutable.js.
import { Map } from 'immutable';
const initialState = Map({
core: Map({
tracker: Map({
activeTrackId: '',
state: 'stopped'
})
})
});
Sau đó, chúng tôi có thể sử dụng API liên tục để thực hiện thay đổi sâu đối với cấu trúc.
return state
.setIn(
['core', 'tracker', 'activeTrackId'],
action.state !== 'stopped' ? action.track._id : ''
)
.setIn(
['core', 'tracker', 'state'],
action.state
);
Điều đáng nói là tùy thuộc vào hình dạng trạng thái của bạn, có thể có ý nghĩa hơn khi chia nhỏ và lồng ghép các bộ giảm tốc của bạn.
cấu Sharing
Khi bạn thực hiện một thay đổi đến một đối tượng với ImmutableJS nó làm cho việc sử dụng thực tế là nó thực hiện với băm ánh xạ vector cố gắng chia sẻ hầu hết các cấu trúc giữa các đối tượng cũ và phiên bản sửa đổi.
Khi bạn sử dụng toán tử spread để tạo các chữ mới, bạn buộc phải sao chép nhiều dữ liệu hơn là bạn cần tạo một đối tượng mới.
An toàn
Bạn có thể loại bỏ một lớp lớn các lỗi bằng cách đảm bảo rằng đối tượng không thể được biến đổi.
Với trạng thái có thể thay đổi, có thể chuyển một tham chiếu đối tượng sang một số mã khác, điều này có thể làm biến đổi nó. Việc thay đổi một đối tượng không phải là "lỗi", vì vậy bạn sẽ không được thông báo rằng nó đã bị thay đổi và sẽ không có dấu vết ngăn xếp, có nghĩa là rất khó để tìm ra nơi đột biến đến từ đó.
Bất cứ nơi nào vật thể bất biến của bạn đi, chúng sẽ an toàn.
Hiệu suất
Bạn có thể sử dụng cấu trúc dữ liệu không thay đổi để đưa ra quyết định nâng cao hơn về việc có cập nhật thành phần hay không.
shouldComponentUpdate(nextProps) {
const oldProps = Immutable.fromJS(this.props);
const newProps = Immutable.fromJS(nextProps);
return !Immutable.is(oldProps, newProps);
}
Mặc dù các loại so sánh sâu có vẻ đắt tiền, họ ngăn cản bạn cần phải diff hoặc chạm vào DOM khi các đối tượng không thay đổi.
Điều này sẽ hiệu quả hơn nếu đạo cụ của bạn là đối tượng không thay đổi được, vì fromJS
sẽ không phải tạo lại các cấp lồng nhau.
Câu trả lời hay, Dan! Điều này thực sự giúp tôi hiểu rõ hơn. Tôi đã không chắc chắn liệu có nên sử dụng 'Bản đồ' hay' Bản ghi 'hay cách sử dụng những thứ này. Tôi thấy các tài liệu một chút bối rối ở lần. Tôi tự hỏi tại sao họ chọn sử dụng một định dạng như '.setIn (['core', 'tracker', 'activeTrackId'], value)' trái ngược với '.setIn ('core.tracker.activeTrackId', value)'. – ffxsam
Nếu bạn thích kiểu ký hiệu đó, có các thư viện như [dot-prop-immutable] (https://github.com/debitoor/dot-prop-immutable). –
PS: Thậm chí ngắn hơn, bạn chỉ có thể sử dụng 'Immutable.fromJS' và chuyển nó bất cứ thứ gì, và nó sẽ thiết lập đúng số lượng bản đồ và danh sách cho bạn. – ffxsam