Czy podczas debugowania mogę mieć dostęp do sklepu Redux z poziomu konsoli przeglądarki?

88

Mam testy jednostkowe dla mojego reducers. Jednak kiedy debuguję w przeglądarce, chcę sprawdzić, czy moje akcje zostały poprawnie wywołane i czy stan został odpowiednio zmodyfikowany.

Szukam czegoś takiego:

window._redux.store

... w przeglądarce, więc mogę to wpisać na konsoli i sprawdzić, jak się sprawy mają.

Jak mogę to osiągnąć?

André Pena
źródło
1
Na marginesie, możesz rozważyć użycie Redux Devtools wraz z narzędziemLogMonitor do wizualizacji swoich działań i wynikających z nich stanów.
Michelle Tilley
1
Mówiąc o bezpieczeństwie, czy w trybie kompilacji produkcyjnej jest możliwe odczytanie magazynu z konsoli przeglądarki?
JRichardsz

Odpowiedzi:

151

Jak przeglądać sklep redux na dowolnej stronie, bez zmian w kodzie

Zaktualizuj listopad 2019

Reaguj devtools zmieniły się od czasu mojej oryginalnej odpowiedzi. Nowa componentskarta w devtools Chrome nadal zawiera dane, ale być może będziesz musiał przeszukać trochę więcej.

  1. otwórz chrome devTools
  2. wybierz Componentszakładkę Reaguj devtool
  3. kliknij najwyższy węzeł i poszukaj w prawej kolumnie, storeaby go wyświetlić
  4. powtarzaj krok 3 w dół drzewa, aż znajdziesz store(dla mnie był to 4 poziom)
  5. Teraz możesz wykonać poniższe czynności za pomocą $r.store.getState()

Przykładowy zrzut ekranu

Oryginalna odpowiedź

Jeśli masz reagować narzędzi programistycznych działa można korzystać $r.store.getState();z żadnych zmian w swoim kodzie .

Uwaga: aby to zadziałało, musisz najpierw otworzyć reakcję devtool w oknie narzędzi programistycznych, w przeciwnym razie pojawi się $r is not definedbłąd

  1. otwarte narzędzia programistyczne
  2. kliknij kartę React
  3. upewnij się, że wybrany jest węzeł dostawcy (lub najwyższy)
  4. następnie wpisz $r.store.getState();lub $r.store.dispatch({type:"MY_ACTION"})do konsoli
S.Kiers
źródło
2
Uwaga: aby to zadziałało, musisz zapisać statejako właściwość w komponencie głównym. Jeśli postępujesz zgodnie ze wskazówkami i masz <Provider>komponent najwyższego poziomu, to zadziała dobrze. Po prostu zostałem ugryziony, przenosząc go!
Aidan Feldman,
3
Wypróbuj$r.state.store.getState()
user1032752
4
Wygląda na to $rodnosi się do aktualnie wybranego komponentu w Componentssekcji Narzędzia deweloperskie. I nie wydaje się, aby mieć dostęp do całego storethrough $r, może dlatego używam haków wszędzie, ale mogę zobaczyć tę część sklepu, że mój składnik widać, który jest prawie tak dobra, a czasem więcej do punkt!
Dima Tisnek
2
$r.hooks[0].subHooks[0].subHooks[0].value.store.getState()działa dla tych komponentów, które useSelector... Ob., YMMV w zależności od używanych haków ...
Dima Tisnek
3
Musiałem użyć$r.props.store
Kris Dover
62

let store = createStore(yourApp); window.store = store;

Teraz możesz uzyskać dostęp do sklepu z window.store w konsoli w następujący sposób:

window.store.dispatch({type:"MY_ACTION"})

Adrian Silvescu
źródło
6
i może również uzyskać dostęp do stanu:window.store.getState()
Liran Brimer
13

Możesz użyć oprogramowania pośredniczącego do rejestrowania, jak opisano w Redux Book :

/**
 * Logs all actions and states after they are dispatched.
 */
const logger = store => next => action => {
  console.group(action.type)
  console.info('dispatching', action)
  let result = next(action)
  console.log('next state', store.getState())
  console.groupEnd(action.type)
  return result
}

let createStoreWithMiddleware = applyMiddleware(logger)(createStore)

let yourApp = combineReducers(reducers)
let store = createStoreWithMiddleware(yourApp)

Alternatywnie, możesz zmienić rejestrowanie, aby po prostu dołączać do tablicy globalnej (twojej window._redux) i możesz zajrzeć do tablicy, gdy potrzebujesz informacji o określonym stanie.

Sean Vieira
źródło
1
Lub jeszcze lepiej, skorzystaj z biblioteki takiej jak redux-logger
Anand Sainath
Jeśli importujesz reduktory w ten sposób: importuj reduktory z './reducers/', możesz po prostu użyć let store = createStoreWithMiddleware (reduktory), ponieważ plik './reducers/' zazwyczaj będzie zawierał connectReducers.
Bruce Seymour
7

Zalecane rozwiązanie u mnie nie działa.

Prawidłowe polecenie to:

$r.props.store.getState()
thodwris
źródło
powinien to być komentarz do tych odpowiedzi
gdbdable
6

Jeśli korzystasz z Next JS , możesz uzyskać dostęp do sklepu przez: window.__NEXT_REDUX_STORE__.getState()

Możesz także wysłać akcje, po prostu spójrz na opcje, które masz wwindow.__NEXT_REDUX_STORE__

Satwik Gupta
źródło
1

Jeśli chcesz zobaczyć stan sklepu do debugowania, możesz to zrobić:

#import global from 'window-or-global'
const store = createStore(reducer)
const onStateChange = (function (global) {
  global._state = this.getState()
}.bind(store, global))
store.subscribe(onStateChange)
onStateChange()
console.info('Application state is available via global _state object.', '_state=', global._state)
igor
źródło
1

Inna odpowiedź sugeruje dodanie sklepu do okna, ale jeśli chcesz mieć dostęp do sklepu tylko jako obiekt, możesz zdefiniować getter w oknie.

Ten kod należy dodać w miejscu, w którym skonfigurowałeś swój sklep - w mojej aplikacji jest to ten sam plik, w którym <Provider store={store} />jest wywołany.

Teraz możesz wpisać reduxStorew konsoli, aby pobrać obiekt - i copy(reduxStore)skopiować go do schowka.

  Object.defineProperty(window, 'reduxStore', {
    get() {
      return store.getState();
    },
  });

Możesz to opakować, if (process.env.NODE_ENV === 'development')aby wyłączyć w produkcji.

James Wilson
źródło
-1

Dzięki narzędziom programistycznym React:

const store = [...__REACT_DEVTOOLS_GLOBAL_HOOK__.reactDevtoolsAgent.internalInstancesById.values()].find(e=>e.elementType.name==="Provider").pendingProps.store
VARP-DOH
źródło
1
daje Uncaught TypeError: Cannot read property 'values' of undefinedbłąd
gdbdable
-2

Przede wszystkim musisz zdefiniować sklep w windowobiekcie (możesz go umieścić w swoim configureStorepliku):

window.store = store;

Następnie wystarczy napisać w konsoli:

window.store.getState();

Hop to pomaga.

Alberto Perez
źródło
store jest domyślnie niezdefiniowany w konsoli. Jak to się tam dostało?
Jen S.,
Sklep musiałby być najpierw zdefiniowany w obiekcie okna, zanim będzie można go użyć.
Rafael Rozon
@RafaelRozon Tak, masz rację, zredagowałem odpowiedź, żeby to pokazać.
Alberto Perez