如何在React Redux中访问存储状态?


83

我只是做一个简单的应用程序来学习与redux异步。我已使所有工作正常进行,现在我只想在网页上显示实际状态。现在,我实际上如何在render方法中访问商店的状态?

这是我的代码(所有内容都在一页中,因为我只是在学习):

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

因此,在状态的render方法中,我想item.title从存储中列出所有内容。

谢谢


5
你快到了。您需要使用该react-redux库创建一个商店连接的组件。我强烈建议您使用作者的免费课程来增进您对redux的理解:egghead.io/courses/getting-started-with-redux
ctrlplusb

3
store.getState()实际上是要从商店中读取状态。redux.js.org/docs/api/Store.html#getState
肯尼·沃登

2
感谢您的教程。我不完全了解redux,本教程对我有很大帮助。
公园主义

Answers:


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存储实例。
1ven

28
@BangDaostore为了清楚起见,您应该包括导入。
Kurai Bankusu

5
ReferenceError找不到变量:store
Pete Alvin

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),就无法访​​问道具。如果您尝试获取商店中已存在的商品而​​没有调度另一个获取周期,则必须使用subscribegetState在上store
AnBisw

13

您需要使用Store.getState()获取商店的当前状态。

有关getState()观看简短视频的更多信息。


所以,不要我就改this.props.itemsstore.getState().items?当我这样做时,它不会输出item.title
公园主义

1
@Parkicism看起来您没有为组件进行初始渲染。我强烈建议您观看本课程:egghead.io/courses/getting-started-with-redux
semanser 2016年

1
@Parkicism这不会显示项目,因为在首次渲染应用程序时,尚未收到来自服务器的响应,因此您需要订阅存储,并在每次存储更改时更新组件。
1ven

let store = createStore(todoApp);进入了index.js,我想进入store内部App.js-它的方式是什么?
N Sharma

TypeError:未定义不是对象(正在评估'_redux.Store.getState')
Pete Alvin

6

您不仅仅想做更多的事情 getState。您想对商店中的更改做出反应。

如果您不使用react-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

但是更好的方法是使用react-redux。在这种情况下,您可以像前面提到的那样使用提供程序,然后使用connect将组件连接到商店。


6
该操作员专门要求使用React-Redux。为什么要提供除请求以外的解决方案?
Kermit_ice_tea

ReferenceError找不到变量:store
Pete Alvin

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/


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.