Як отримати доступ до стану магазину в React Redux?


83

Я просто роблю просту програму, щоб навчитися асинхронізації за допомогою redux. У мене все працює, тепер я просто хочу відобразити фактичний стан на веб-сторінці. Тепер, як я дійсно можу отримати доступ до стану магазину в методі візуалізації?

Ось мій код (все на одній сторінці, бо я тільки вчуся):

const initialState = {
        fetching: false,
        fetched: false,
        items: [],
        error: null
    }

const reducer = (state=initialState, action) => {
    switch (action.type) {
        case "REQUEST_PENDING": {
            return {...state, fetching: true};
        }
        case "REQUEST_FULFILLED": {
            return {
                ...state,
                fetching: false,
                fetched: true,
                items: action.payload
            }
        }
        case "REQUEST_REJECTED": {
            return {...state, fetching: false, error: action.payload}   
        }
        default: 
            return state;
    }
};

const middleware = applyMiddleware(promise(), thunk, logger());
const store = createStore(reducer, middleware);

store.dispatch({
    type: "REQUEST",
    payload: fetch('http://localhost:8000/list').then((res)=>res.json())
});

store.dispatch({
    type: "REQUEST",
    payload: fetch('http://localhost:8000/list').then((res)=>res.json())
});

render(
    <Provider store={store}>
        <div>
            { this.props.items.map((item) => <p> {item.title} </p> )}
        </div>
    </Provider>,
    document.getElementById('app')
);

Отже, у методі візуалізації штату я хочу перерахувати все item.titleз магазину.

Дякую


5
Ви майже там. Вам потрібно створити компонент, підключений до магазину, використовуючи react-reduxбібліотеку. Я настійно рекомендую вам відшліфувати своє розуміння редуксу за допомогою безкоштовного курсу від автора: egghead.io/courses/getting-started-with-redux
ctrlplusb

3
Ви store.getState()дійсно читаєте стан зі свого магазину. redux.js.org/docs/api/Store.html#getState
Кенні Ворден

2
Дякую за підручник. Я не повністю розумію redux, і цей посібник мені дуже допоможе.
Паркізм

Відповіді:


62

Вам слід створити окремий компонент, який буде прослуховувати зміни стану та оновлюватись при кожній зміні стану:

import store from '../reducers/store';

class Items extends Component {
  constructor(props) {
    super(props);

    this.state = {
      items: [],
    };

    store.subscribe(() => {
      // When state will be updated(in our case, when items will be fetched), 
      // we will update local component state and force component to rerender 
      // with new data.

      this.setState({
        items: store.getState().items;
      });
    });
  }

  render() {
    return (
      <div>
        {this.state.items.map((item) => <p> {item.title} </p> )}
      </div>
    );
  }
};

render(<Items />, document.getElementById('app'));

60
@ 1ven як отримати storeвизначену тут змінну?
Bang Dao

3
@BangDao ми можемо припустити, що ми імпортуємо його із зовнішнього файлу. storeзмінна - це екземпляр магазину redux.
вересня

28
@BangDao Ви повинні включити storeімпорт для ясності.
Kurai Bankusu

5
ReferenceError Не вдається знайти змінну: store
Піт Елвін

4
import store from '../reducers/store';. і store.jsміститимеconst createStoreWithMiddleware = applyMiddleware(thunkMiddleware,promise)(createStore); export default createStoreWithMiddleware(reducers);
AnBisw

44

Імпорт connectз react-reduxі використовувати його для підключення компонента зі станомconnect(mapStates,mapDispatch)(component)

import React from "react";
import { connect } from "react-redux";


const MyComponent = (props) => {
    return (
      <div>
        <h1>{props.title}</h1>
      </div>
    );
  }
}

Нарешті, вам потрібно зіставити штати з реквізитом, щоб отримати до них доступ this.props

const mapStateToProps = state => {
  return {
    title: state.title
  };
};
export default connect(mapStateToProps)(MyComponent);

Доступними будуть лише ті штати, через які ви складаєте карту props

Перевірте цю відповідь: https://stackoverflow.com/a/36214059/4040563

Для подальшого читання: https://medium.com/@atomarranger/redux-mapstatetoprops-and-mapdispatchtoprops-shorthand-67d6cd78f132


1
ПРИМІТКА. Таким чином, реквізити не будуть доступні без виклику дії (визначеної в mapDispatchToProps). Якщо ви намагаєтеся отримати те, що вже є в магазині, не відправляючи черговий цикл отримання, вам доведеться використовувати subscribeабо getStateна store.
AnBisw

13

Вам потрібно використовувати, Store.getState()щоб отримати поточний стан вашого магазину.

Для отримання додаткової інформації про getState()перегляд цього короткого відео.


Тож я просто переходжу this.props.itemsна store.getState().items? Коли я це зробив, це не виводить item.title.
Паркізм

1
@Parkicism схоже на те, що ви не робили початковий візуалізацію для свого компонента. Я настійно рекомендую вам переглянути цей курс: egghead.io/courses/getting-started-with-redux
semanser

1
@Parkicism це не відображає елементи, тому що коли додаток відображається вперше, відповідь від сервера ще не отримана, вам потрібно підписатись на store, щоб оновлювати компонент при кожному зміні магазину.
квітня

У мене let store = createStore(todoApp);всередині index.jsі я хочу отримати доступ storeвсередину App.js- Який це шлях?
N Sharma

TypeError: undefined не є об'єктом (оцінюючи '_redux.Store.getState')
Піт Елвін

6

Ви хочете зробити більше, ніж просто getState. Ви хочете реагувати на зміни в магазині.

Якщо ви не використовуєте response-redux, ви можете зробити це:

function rerender() {
    const state = store.getState();
    render(
        <div>
            { state.items.map((item) => <p> {item.title} </p> )}
        </div>,
        document.getElementById('app')
    );
}

// subscribe to store
store.subscribe(rerender);

// do initial render
rerender();

// dispatch more actions and view will update

Але краще використовувати реакцію-відновлення. У цьому випадку ви використовуєте постачальника, як ви вже згадували, але потім використовуєте підключення для підключення компонента до магазину.


6
Оператор спеціально попросив React-Redux. Навіщо надавати рішення для чогось іншого, крім запиту?
Kermit_ice_tea

ReferenceError Не вдається знайти змінну: store
Піт Елвін

3

Якщо ви хочете виконати якусь потужну налагодження, ви можете підписатися на кожну зміну стану і призупинити програму, щоб детально побачити, що відбувається, наступним чином.

store.js
store.subscribe( () => {
  console.log('state\n', store.getState());
  debugger;
});

Помістіть це у файл, де ви робите createStore.

Щоб скопіювати stateоб’єкт із консолі в буфер обміну, виконайте такі дії:

  1. Клацніть правою кнопкою миші на об’єкті на консолі Chrome та виберіть у контекстному меню пункт Зберегти як глобальну змінну. Він поверне щось на зразок temp1 як ім'я змінної.

  2. Chrome також має copy()метод, тому copy(temp1)в консолі слід скопіювати цей об’єкт у ваш буфер обміну.

https://stackoverflow.com/a/25140576

https://scottwhittaker.net/chrome-devtools/2016/02/29/chrome-devtools-copy-object.html

Ви можете переглянути об'єкт у засобі перегляду json, як цей: http://jsonviewer.stack.hu/

Ви можете порівняти два об'єкти json тут: http://www.jsondiff.com/


хороша стаття теж coderwall.com/p/pafnew/redux-middleware-logger
zloctb
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.