简体   繁体   English

如何处理react / redux中的副作用?

[英]How to handle side effects in react/redux?

I'm having some trouble figuring out where to stick an async side-effects handler in my react/redux application. 我在弄清楚应在我的react / redux应用程序中放置异步副作用处理程序的地方遇到了一些麻烦。

I'm using react-router, and all of my root (or almost root) level containers are calling dispatch and receiving updates with no problem. 我正在使用react-router,并且我所有的根(或几乎根)级别的容器都在调用调度并毫无问题地接收更新。 The complication is where async services fit into this. 复杂之处在于异步服务适合于此。 Here's an example: 这是一个例子:

Routes 路线

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

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. Locations容器通常也很笨,但是困扰我的是_onFetch()方法,该方法由在Stores组件内部单击按钮触发。

onFetch() is dispatching that action, which is setting the status to "fetching", but it's also interacting with StoreService, which feels smelly. onFetch()正在分派该操作,该操作将状态设置为“正在抓取”,但它也与StoreService交互,感觉很臭。 How should this be handled? 应该如何处理? So that Locations can just dispatch the action and wait for its props to be updated? 这样,Locations就可以调度动作并等待其道具更新了吗?

What I've considered 我考虑过的

I have thought about moving all API interactions to the top level "app" container, but that still doesn't feel quite right. 我曾考虑过将所有API交互都移至顶级“应用”容器,但这仍然感觉不太正确。 Is it possible to subscribe a "headless" listener to the application state? 是否可以将“无头”侦听器订阅到应用程序状态? ie 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进行任何异步,setinterval等副作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM