2016-03-19 23 views
5

Ưu điểm của việc sử dụng Immutable với React (và tùy chọn, Redux) là gì? Trong Redux, tôi chỉ đơn giản là có thể sử dụng nghỉ ngơi này trong gia giảm của tôi để trả lại một trạng thái mới:React, Redux, and Immutable

const initialState = { 
    activeTrackId: '', 
    state: 'stopped', 
}; 

export default function (state = initialState, action) { 
    switch (action.type) { 
    case actions.PROCESS_TRACK_ACTION: 
     return { 
     ...state, 
     activeTrackId: action.state !== 'stopped' ? action.track._id : '', 
     state: action.state, 
     }; 
     // ... 

Kịch bản duy nhất mà tôi đã tìm thấy nó hữu ích trong việc là thế này:

shouldComponentUpdate(nextProps) { 
    const oldProps = Immutable.fromJS(this.props); 
    const newProps = Immutable.fromJS(nextProps); 

    return !Immutable.is(oldProps, newProps); 
} 

Và đó thậm chí có thể lạm dụng nó, theo như tôi biết.

Có thể ai đó có thể khai sáng cho tôi là lợi thế của việc sử dụng Không thể thay đổi trong bối cảnh Phản ứng và Redux?

Trả lời

5

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.

+0

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

+0

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). –

+0

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

1

Nếu bạn cẩn thận, không làm biến đổi thuộc tính được truyền, bạn không phải sử dụng Immutable.js.

Kể từ khi props tham chiếu bất kỳ thay đổi nào đối với nó sẽ ảnh hưởng đến toàn bộ ứng dụng.

Immutable.js đảm bảo rằng chúng không thể sửa đổi được nhưng nó có tác động hiệu suất trên các ứng dụng lớn nếu bạn không thực hiện đột biến, nhưng lợi ích là, nó ngăn chặn bất kỳ tình trạng ô nhiễm ngẫu nhiên nào của trạng thái ứng dụng.

Bạn có thể xem these videos để được giải thích chi tiết.

Các vấn đề liên quan