【问题标题】:How to use react-redux store with Async HTTP Request如何使用带有异步 HTTP 请求的 react-redux 存储
【发布时间】:2016-05-11 18:09:17
【问题描述】:

我正在尝试使用 AJAX 调用更新带有数字的 div。这是小部件:

import {store} from './Store';

class Widget extends React.Component {
    constructor(props) {
        super(props);
    }
    componentWillMount() {
        let req = function() {
            let xhr = new XMLHttpRequest();
            xhr.open('GET', this.props.apiUrl, true);
            xhr.onreadystatechange = function() {
                if (xhr.readyState === 4) {
                    if (xhr.response) {
                        store.dispatch({
                            type: 'SET_STATE',
                            state: {
                                foo: JSON.parse(xhr.response)
                            }
                        });
                    }
                }
            }.bind(this);
            xhr.send();
        }
        req.call(this);
    }
    render() {
        return(
            <widget>
                <div>{this.props.foo}</div>
            </widget>
        );
    }
}

这里是“减速器”:

import {List, Map} from 'immutable';
export default function(state = Map(), action) {
    switch(action.type) {
        case 'SET_STATE':
            return state.merge(action.state);
    }
    return state;
}

这里是商店:

import {createStore} from 'redux';
import reducer from '../reducer';

export const store = createStore(reducer);

当我运行此代码时,我会加载要加载的页面,但 foo 未定义。该请求返回带有正确数据的响应。 dispatch() 被正确调用。如何异步触发在整个应用中传播的状态更改?

注意

拜托,拜托,拜托不要将我转发到像 thisthis 这样的冗长抽象博客文章。我需要一个使用store.dispatch() 触发状态更改的代码的实际工作示例。谢谢。

【问题讨论】:

  • 你没有使用react-redux 吗?
  • 一旦你的 reducer 运行,它应该触发并重新渲染,这取决于你连接组件的方式。
  • 我猜这个组件不是connected
  • 你缺少 react-redux 绑定 redux.js.org/docs/basics/UsageWithReact.html
  • @azium 我将store 作为组件导入。请看更新

标签: javascript reactjs redux react-redux


【解决方案1】:

正如 cmets 中提到的 Azium,您不需要 redux-thunk 来执行此操作,但是您可以这样做。

您将 redux-thunk 中间件应用到您的商店:

var thunk = require('redux-thunk');
const store = createStore(
    combineReducers({
        reducer1,
        reducer2
    }),
    applyMiddleware(thunk)
);

然后你可以像这样定义动作:

export const getData = () => {
    return (dispatch) => {
        return fetch('/foo')
            .then((response) => response.json())
            .then((json) => dispatch(receieveData(json)));
    };
};

receieveData 是您定义的另一个操作。

现在您可以在 componentWillMount 中调用此操作。我可能错过了一些东西,但这就是它的要点。这一切都在您原始帖子的第一个链接中 (http://redux.js.org/docs/advanced/AsyncActions.html)。

编辑:当然,正如许多人已经说过的,你需要 react-redux :)

【讨论】:

    【解决方案2】:

    我发现出了什么问题。我没有设置初始状态。

    // Store.jsx
    
    import {fromJS} from 'immutable';
    import {createStore} from 'redux';
    import reducer from '../reducer';
    
    export const store = createStore(reducer);
    store.dispatch({
        type:'SET_STATE',
        state: fromJS({
            foo: 0
        })
    })
    

    没有这个,被更新的状态总是null。这个简单的事实不在任何官方的 React/Redux 文档中。

    【讨论】:

      猜你喜欢
      • 2019-12-09
      • 1970-01-01
      • 1970-01-01
      • 2018-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-05
      • 1970-01-01
      相关资源
      最近更新 更多