Programing

Redux 앱에서 localStorage에 쓸 위치는 어디입니까?

crosscheck 2020. 6. 15. 21:45
반응형

Redux 앱에서 localStorage에 쓸 위치는 어디입니까?


상태 트리의 일부를 localStorage에 유지하고 싶습니다. 적절한 장소는 무엇입니까? 감속기 또는 행동?


감속기는 순수해야하며 부작용이 없어 감속기를 사용하기에 적절한 장소는 아닙니다.

구독자에서 수행하는 것이 좋습니다.

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

상점을 작성하기 전에 지속 된 파트를 읽으십시오.

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

사용 combineReducers()하면 상태를받지 못한 감속기가 기본 state인수 값을 사용하여 정상적으로 "부팅"됩니다 . 이것은 매우 편리 할 수 ​​있습니다.

localStorage에 너무 빨리 쓰지 않거나 구독자에게 문제를 일으키지 않으면 성능 문제가 발생하는 것이 좋습니다.

마지막으로,이를 대안으로 캡슐화하는 미들웨어를 작성할 수 있지만, 더 간단한 솔루션이기 때문에 구독자로 시작합니다.


Dan Abramov의 대답의 빈칸을 채우려면 store.subscribe()다음과 같이 사용할 수 있습니다 .

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

상점을 작성하기 전에 localStorage다음과 같이 키 아래의 JSON을 확인 하고 구문 분석하십시오.

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

그런 다음이 peristedState상수를 다음 createStore과 같이 메소드에 전달 하십시오.

const store = createStore(
  reducer, 
  persistedState,
  /* any middleware... */
)

한마디로 : 미들웨어.

redux-persist를 확인하십시오 . 또는 직접 작성하십시오.

[업데이트 2016. 12. 18] 현재 비활성 또는 더 이상 사용되지 않는 두 개의 유사한 프로젝트에 대한 언급을 제거하도록 편집되었습니다.


위의 솔루션에 문제가있는 사람은 직접 작성할 수 있습니다. 내가 한 일을 보여 드리겠습니다. saga middleware두 가지 localStorageMiddlewarereHydrateStore방법 에 중점을 두는 것은 무시하십시오 . localStorageMiddleware손잡이 모두 redux state와 풋을 local storage하고 rehydrateStore모든 당겨 applicationState로컬 저장소에 존재하는 경우와 그것의 풋redux 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;

@Gardezi에 대답 할 수는 없지만 그의 코드를 기반으로 한 옵션은 다음과 같습니다.

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
    )
);

차이점은 우리는 단지 몇 가지 행동을 저장한다는 것입니다. 당신은 이벤트의 디 바운스 함수를 사용하여 상태의 마지막 상호 작용 만 저장할 수 있습니다


조금 늦었지만 여기에 언급 된 예에 따라 지속적인 상태를 구현했습니다. X 초마다 상태를 업데이트하려는 경우이 방법이 도움이 될 수 있습니다.

  1. 랩퍼 함수 정의

    let oldTimeStamp = (Date.now()).valueOf()
    const millisecondsBetween = 5000 // Each X milliseconds
    function updateLocalStorage(newState)
    {
        if(((Date.now()).valueOf() - oldTimeStamp) > millisecondsBetween)
        {
            saveStateToLocalStorage(newState)
            oldTimeStamp = (Date.now()).valueOf()
            console.log("Updated!")
        }
    }
    
  2. 구독자에서 랩퍼 함수 호출

        store.subscribe((state) =>
        {
        updateLocalStorage(store.getState())
         });
    

In this example, the state is updated at most each 5 seconds, regardless how often an update is triggered.

참고URL : https://stackoverflow.com/questions/35305661/where-to-write-to-localstorage-in-a-redux-app

반응형