Làm cách nào để truy cập trạng thái cửa hàng trong React Redux?


83

Tôi chỉ đang tạo một ứng dụng đơn giản để học async với redux. Tôi đã làm cho mọi thứ hoạt động, bây giờ tôi chỉ muốn hiển thị trạng thái thực tế trên trang web. Bây giờ, làm cách nào để thực sự truy cập trạng thái của cửa hàng trong phương thức kết xuất?

Đây là mã của tôi (mọi thứ nằm trong một trang vì tôi chỉ đang học):

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

Vì vậy, trong phương thức kết xuất của trạng thái, tôi muốn liệt kê tất cả những thứ item.titletừ cửa hàng.

Cảm ơn


5
Bạn gần như ở đó. Bạn cần tạo một thành phần kết nối cửa hàng bằng cách sử dụng react-reduxthư viện. Tôi rất khuyên bạn đánh bóng hiểu biết của bạn Redux với khóa học miễn phí của tác giả: egghead.io/courses/getting-started-with-redux
ctrlplusb

3
Bạn store.getState()thực sự đọc trạng thái từ cửa hàng của bạn. redux.js.org/docs/api/Store.html#getState
Kenny Worden

2
Cảm ơn vì hướng dẫn. Tôi không hiểu hết về redux và hướng dẫn này sẽ giúp tôi rất nhiều.
Parkicism

Câu trả lời:


62

Bạn nên tạo thành phần riêng biệt, thành phần này sẽ lắng nghe các thay đổi trạng thái và cập nhật mỗi khi thay đổi trạng thái:

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 làm thế nào để chúng ta có được storebiến được định nghĩa ở đây?
Bang Dao

3
@BangDao chúng tôi có thể giả định rằng chúng tôi đang nhập nó từ tệp bên ngoài. storebiến - nó là phiên bản cửa hàng redux.
1ven

28
@BangDao Bạn nên bao gồm storenhập cho rõ ràng.
Kurai Bankusu

5
ReferenceError Không thể tìm thấy biến: cửa hàng
Pete Alvin

4
import store from '../reducers/store';. và store.jssẽ chứaconst createStoreWithMiddleware = applyMiddleware(thunkMiddleware,promise)(createStore); export default createStoreWithMiddleware(reducers);
AnBisw,

44

Nhập connecttừ react-reduxvà sử dụng nó để kết nối thành phần với trạng tháiconnect(mapStates,mapDispatch)(component)

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


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

Cuối cùng, bạn cần ánh xạ các trạng thái đến các đạo cụ để truy cập chúng bằng this.props

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

Chỉ các tiểu bang mà bạn lập bản đồ mới có thể truy cập được qua props

Kiểm tra câu trả lời sau: https://stackoverflow.com/a/36214059/4040563

Để đọc thêm: https://medium.com/@atomarranger/redux-mapstatetoprops-and-mapdispatchtoprops-shorthand-67d6cd78f132


1
LƯU Ý: Bằng cách này, các đạo cụ sẽ không thể truy cập được nếu không gọi hành động (được định nghĩa trong mapDispatchToProps). Nếu bạn đang cố gắng lấy những gì đã có trong cửa hàng mà không gửi một chu kỳ tìm nạp khác thì bạn sẽ phải sử dụng một trong hai subscribehoặc getStatetrên store.
AnBisw

13

Bạn cần sử dụng Store.getState()để có được trạng thái hiện tại của Cửa hàng của mình.

Để biết thêm thông tin về getState()xem này đoạn video ngắn.


Vì vậy, tôi chỉ cần thay đổi this.props.itemsthành store.getState().items? Khi tôi làm điều đó, nó không xuất ra item.title.
Parkicism

1
@Parkicism có vẻ như bạn không kết xuất ban đầu cho thành phần của mình. Tôi thực sự khuyên bạn nên xem khóa học này: egghead.io/courses/getting-started-with-redux
semanser,

1
@Parkicism này không hiển thị các mục, vì khi ứng dụng hiển thị lần đầu tiên, phản hồi từ máy chủ chưa nhận được, bạn cần đăng ký lưu trữ, để cập nhật thành phần mỗi khi cửa hàng thay đổi.
1

Tôi có let store = createStore(todoApp);trong index.jsvà tôi muốn truy cập vào storebên trong App.js- Cách của nó là gì?
N Sharma

TypeError: undefined không phải là một đối tượng (đánh giá '_redux.Store.getState')
Pete Alvin

6

Bạn muốn làm nhiều hơn là chỉ getState. Bạn muốn phản ứng với những thay đổi trong cửa hàng.

Nếu bạn không sử dụng react-redux, bạn có thể làm như sau:

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

Nhưng tốt hơn là sử dụng react-redux. Trong trường hợp này, bạn sử dụng Nhà cung cấp như bạn đã đề cập, nhưng sau đó sử dụng kết nối để kết nối thành phần của bạn với cửa hàng.


6
Op yêu cầu cụ thể cho React-Redux. Tại sao phải cung cấp giải pháp cho thứ gì đó khác với yêu cầu?
Kermit_ice_tea

ReferenceError Không thể tìm thấy biến: cửa hàng
Pete Alvin

3

Nếu bạn muốn thực hiện một số gỡ lỗi mạnh mẽ, bạn có thể đăng ký mọi thay đổi của trạng thái và tạm dừng ứng dụng để xem những gì đang diễn ra chi tiết như sau.

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

Đặt nó vào tệp nơi bạn làm createStore.

Để sao chép stateđối tượng từ bảng điều khiển vào khay nhớ tạm, hãy làm theo các bước sau:

  1. Nhấp chuột phải vào một đối tượng trong bảng điều khiển của Chrome và chọn Store dưới dạng Global Variable từ menu ngữ cảnh. Nó sẽ trả về một cái gì đó giống như temp1 làm tên biến.

  2. Chrome cũng có một copy()phương thức, vì vậy copy(temp1)trong bảng điều khiển nên sao chép đối tượng đó vào khay nhớ tạm của bạn.

https://stackoverflow.com/a/25140576

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

Bạn có thể xem đối tượng trong trình xem json như thế này: http://jsonviewer.stack.hu/

Bạn có thể so sánh hai đối tượng json tại đây: http://www.jsondiff.com/


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.