Як отримати доступ до стану магазину в 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.