如何调度Redux存储数据而不必在React组件中接收它?

时间:2018-02-05 18:25:31

标签: reactjs redux react-redux

如果Redux存储中有数据需要通过调度异步操作发送到服务器,那么如何调度它而不必在React组件内接收它,因为这些数据不用于渲染任何内容。

示例:

我的商店:

{
  dataNotUsedForRendering: 'A',
  dataUsedForRendering: 'B'
}

我的组件:

class MyComponent extends React.Component {
    //...

    render(){
        const {dataUsedForRendering, dataNotUsedForRendering, dispatch} = this.props;

     return (
     <div>
        {dataUsedForRendering}
        <button onClick={()=> dispatch({type: 'SAVE', payload: dataNotUsedForRendering})}>Save</button>
     </div>);
    }
}

export const mapStateToProps = (state) => ({
    dataUsedForRendering: state.dataUsedForRendering,
    dataNotUsedForRendering: state.dataNotUsedForRendering
});

export default connect(mapStateToProps)(MyComponent);

此处dataNotUsedForRendering作为MyComponent中的prop被接收,仅仅是为了将其发送到服务器。

我尝试了mapDispatchToProps,但我获得了Connect(MyComponent)而不是MyComponent的道具。

2 个答案:

答案 0 :(得分:1)

以下是使用redux-thunk实现这一目标的方法。您的组件会发生变化,以便它对dataNotUsedForRendering一无所知,并导入save操作:

import { save } from './actions';

class MyComponent extends React.Component {
    render() {
        const {dataUsedForRendering, dispatch} = this.props;

        return (
            <div>
                {dataUsedForRendering}
                <button onClick={() => dispatch(save())}>Save</button>
            </div>
        );
    }
}

export const mapStateToProps = (state) => ({
    dataUsedForRendering: state.dataUsedForRendering
});

export default connect(mapStateToProps)(MyComponent);

然后你的行动:

export const save = () => (dispatch, getState) => {
    dispatch({
        type: 'SAVE',
        payload: getState().dataNotUsedForRendering
    });
};

编辑:但您可能不需要这样做。您只需访问/修改减速器中的dataNotUsedForRendering即可。如果您只是将这些数据从商店中取出以将其保存在该州的其他部分,请考虑规范化您的商店并在适当的时候跨多个减少商处理您的操作。

答案 1 :(得分:1)

Redux saga等价于@LukeMWillis' answer

const selectDataNotUsedForRendering = state => state.dataNotUsedForRendering;

const dataNotUsedForRendering = yield select(selectDataNotUsedForRendering);

yield put({
  type: 'SAVE',
  payload: dataNotUsedForRendering
});