如何处理 react/redux 中的副作用? [英] How to handle side effects in react/redux?

查看:62
本文介绍了如何处理 react/redux 中的副作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在确定在我的 react/redux 应用程序中放置异步副作用处理程序的位置时遇到了一些麻烦.

I'm having some trouble figuring out where to stick an async side-effects handler in my react/redux application.

我正在使用 react-router,并且我所有的根(或几乎是根)级别的容器都可以毫无问题地调用调度和接收更新.复杂之处在于异步服务适合于此.举个例子:

I'm using react-router, and all of my root (or almost root) level containers are calling dispatch and receiving updates with no problem. The complication is where async services fit into this. Here's an example:

路线

<Route path='/' component={App}>
    <Route path='/home' component={Home} />
    <Route path='/locations' component={Locations} />
    <Route path='/something-else' component={SomethingElse} />
</Route>

让我们看看位置,我们需要获取某些东西可能并不奇怪:

Let's take a look at locations, where it's probably not a surprise that we need to fetch something:

class Locations extends React.Component<LocationsProps, void> {
    private _service: StoreService;

    constructor(props) {
        super(props);
        this._service = new StoreService();
    }

    render(): JSX.Element {
        const { status, stores, selectedStore } = this.props;
        return (
            <fieldset>
                <h1>Locations</h1>
                <StoresComponent 
                    status={status} 
                    stores={stores} 
                    selectedStore={selectedStore}
                    onFetch={this._onFetch.bind(this)}
                    onSelect={this._onStoreSelect.bind(this)} />
            </fieldset>
        );  
    }

    private _onFetch(): void {
        const { dispatch } = this.props;
        dispatch(fetchStores());

        this._service.find()
            .then(stores => dispatch(loadStores(stores)));
    }

    private _onStoreSelect(id: string): void {
        const { dispatch } = this.props;
        dispatch(selectStore(id));
    }

    static contextTypes: React.ValidationMap<any> = {
        status: React.PropTypes.string,
        stores: React.PropTypes.arrayOf(React.PropTypes.object)
    };
}

function mapStateToProps(state) {
    return {
        status: state.stores.status,
        stores: state.stores.list,
        selectedStore: state.stores.selectedStore
    };
}

export default connect(mapStateToProps)(Locations);

我有一个非常愚蠢的商店组件,它依赖于它的容器来完成大部分工作.Locations 容器大部分也很笨,但让我烦恼的部分是 _onFetch() 方法,它由 Stores 组件内的按钮点击触发.

I have a very dumb stores component that relies on its container to do most of the work. The Locations container is mostly dumb as well, but the part that bothers me is the _onFetch() method, triggered by a button click inside of the Stores component.

onFetch() 正在调度该操作,将状态设置为正在获取",但它也在与 StoreService 交互,这感觉很臭.应该如何处理这种情况?这样 Locations 就可以调度 action 并等待它的 props 更新?

onFetch() is dispatching that action, which is setting the status to "fetching", but it's also interacting with StoreService, which feels smelly. How should this be handled? So that Locations can just dispatch the action and wait for its props to be updated?

我考虑过的

我曾考虑将所有 API 交互移至顶级应用"容器,但这仍然感觉不太对.是否可以订阅应用程序状态的无头"侦听器?即不渲染任何东西,只监视获取请求并触发类似的东西:

I have thought about moving all API interactions to the top level "app" container, but that still doesn't feel quite right. Is it possible to subscribe a "headless" listener to the application state? i.e. something that doesn't render anything, and only watches for fetch requests and fires off something like:

this._storeService.find()
    .then(stores => dispatch(loadStores(stores)));

推荐答案

使用 sagas 来做任何副作用,比如 async、setinterval 等.

Use sagas to do any side effects like async, setinterval etc.

这篇关于如何处理 react/redux 中的副作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆