Helpex - Trao đổi & giúp đỡ Đăng nhập
124

Tôi muốn duy trì một số phần của cây trạng thái của mình cho localStorage. Nơi thích hợp để làm như vậy là gì? Giảm hay hành động?

124 hữu ích 0 bình luận 52k xem chia sẻ
170

Reducer không bao giờ là một nơi thích hợp để làm điều này bởi vì các chất làm giảm nên tinh khiết và không có tác dụng phụ.

Tôi khuyên bạn chỉ nên làm điều đó trong một thuê bao:

store.subscribe(() => {
  // persist your state
})

Trước khi tạo cửa hàng, hãy đọc những phần vẫn tồn tại:

const persistedState = // ...
const store = createStore(reducer, persistedState)

Nếu bạn sử dụng, combineReducers()bạn sẽ nhận thấy rằng các bộ giảm tốc chưa nhận được trạng thái sẽ khởi động lại như bình thường bằng stategiá trị đối số mặc định của chúng . Điều này có thể khá tiện dụng.

Bạn nên gỡ bỏ thuê bao của mình để không viết thư cho localStorage quá nhanh hoặc bạn sẽ gặp vấn đề về hiệu suất.

Cuối cùng, bạn có thể tạo một phần mềm trung gian đóng gói nó như một giải pháp thay thế, nhưng tôi bắt đầu với một người đăng ký vì đó là một giải pháp đơn giản hơn và thực hiện tốt công việc.

170 hữu ích 5 bình luận chia sẻ
119

Để điền vào chỗ trống trong câu trả lời của Dan Abramov, bạn có thể sử dụng store.subscribe()như thế này:

store.subscribe(()=>{
  localStorage.setItem('reduxState', JSON.stringify(store.getState()))
})

Trước khi tạo cửa hàng, hãy kiểm tra localStoragevà phân tích bất kỳ JSON nào dưới khóa của bạn như thế này:

const persistedState = localStorage.getItem('reduxState') ? JSON.parse(localStorage.getItem('reduxState')) : {}

Sau đó, bạn truyền peristedStatehằng số này cho createStorephương thức của bạn như thế này:

const store = createStore(
  reducer, 
  persistedState,
  /* any middleware... */
)
119 hữu ích 5 bình luận chia sẻ
42

Trong một từ: phần mềm trung gian.

Kiểm tra redux-kiên trì . Hoặc viết cho riêng bạn.

[CẬP NHẬT ngày 18 tháng 12 năm 2016] Đã chỉnh sửa để xóa đề cập đến hai dự án tương tự hiện không hoạt động hoặc không dùng nữa.

42 hữu ích 0 bình luận chia sẻ
7

Nếu bất cứ ai đang có bất kỳ vấn đề với các giải pháp trên, bạn có thể viết riêng của bạn. Hãy để tôi chỉ cho bạn những gì tôi đã làm. Bỏ qua saga middlewaremọi thứ chỉ tập trung vào hai điều localStorageMiddlewarereHydrateStorephương pháp. các localStorageMiddlewarekéo tất cả các redux statevà đặt nó trong local storagerehydrateStorekéo tất cả các applicationStatetrong lưu trữ địa phương nếu hiện tại và đặt nó trongredux store

import {createStore, applyMiddleware} from 'redux'
import createSagaMiddleware from 'redux-saga';
import decoristReducers from '../reducers/decorist_reducer'

import sagas from '../sagas/sagas';

const sagaMiddleware = createSagaMiddleware();

/**
 * Add all the state in local storage
 * @param getState
 * @returns {function(*): function(*=)}
 */
const localStorageMiddleware = ({getState}) => { // <--- FOCUS HERE
    return (next) => (action) => {
        const result = next(action);
        localStorage.setItem('applicationState', JSON.stringify(
            getState()
        ));
        return result;
    };
};


const reHydrateStore = () => { // <-- FOCUS HERE

    if (localStorage.getItem('applicationState') !== null) {
        return JSON.parse(localStorage.getItem('applicationState')) // re-hydrate the store

    }
}


const store = createStore(
    decoristReducers,
    reHydrateStore(),// <-- FOCUS HERE
    applyMiddleware(
        sagaMiddleware,
        localStorageMiddleware,// <-- FOCUS HERE 
    )
)

sagaMiddleware.run(sagas);

export default store;
7 hữu ích 1 bình luận chia sẻ
1

Tôi không thể trả lời @Gardezi nhưng một tùy chọn dựa trên mã của anh ấy có thể là:

const rootReducer = combineReducers({
    users: authReducer,
});

const localStorageMiddleware = ({ getState }) => {
    return next => action => {
        const result = next(action);
        if ([ ACTIONS.LOGIN ].includes(result.type)) {
            localStorage.setItem(appConstants.APP_STATE, JSON.stringify(getState()))
        }
        return result;
    };
};

const reHydrateStore = () => {
    const data = localStorage.getItem(appConstants.APP_STATE);
    if (data) {
        return JSON.parse(data);
    }
    return undefined;
};

return createStore(
    rootReducer,
    reHydrateStore(),
    applyMiddleware(
        thunk,
        localStorageMiddleware
    )
);

sự khác biệt là chúng tôi chỉ lưu một số hành động, bạn có thể sử dụng chức năng gỡ lỗi để chỉ lưu tương tác cuối cùng của trạng thái của bạn

1 hữu ích 0 bình luận chia sẻ
loading
Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ javascript redux local-storage state , hoặc hỏi câu hỏi của bạn.

Có thể bạn quan tâm

loading