【问题标题】:Trigger an action on event with react-redux使用 react-redux 触发事件动作
【发布时间】:2017-04-04 09:49:00
【问题描述】:

我正在使用 react / redux / react-redux 来实现一个执行 ajax 请求的模态表单。

如果我是正确的,react-redux 可以让你:

  • 将 redux 存储中的数据显示到您的组件中
  • 将事件从容器分发到 redux

我也在使用 redux-saga 来处理 redux 触发的 Ajax 请求。

但是,当从 Redux 触发特定事件时,我不知道如何触发操作(例如:关闭模态表单)。

代码示例:

class MyFormDialog extends React.Component {
    state = {
        open: false,
    };


    handleOpen = () => {
        this.setState({open: true});
    };

    handleClose = () => {
        this.setState({open: false});
    };

    render() {
        const actions = [
            <FlatButton
                label="Cancel"
                onTouchTap={this.handleClose}
            />,
            <FlatButton
                label="Submit"
                onTouchTap={this.props.ajaxRequest}
            />,
        ];

        return (
            <div>
                <MenuItem primaryText="Make a request"  onTouchTap={this.handleOpen}/>
                <Dialog
                    title="Make a request"
                    actions={actions}
                    modal={true}
                    open={this.state.open}
                    onRequestClose={this.handleClose} />
            </div>
        );
    }
}

const mapStateToProps = (state, ownProps) => {
    return {
        loading: state.isLoading,
        success: state.success,
        error: state.error,
    }
};

const mapDispatchToProps = (dispatch, ownProps) => {
    return {
        ajaxRequest: (url, tags) => {
            dispatch({type: "AJAX_REQUESTED"})
        },
    }
};

const ConnectedMyFormDialog = connect(
    mapStateToProps,
    mapDispatchToProps
)(MyFormDialog );

export default ConnectedMyFormDialog ;

Reducer 的构建如下:

  • 发送AJAX_REQUESTEDisLoading = true(其他设置为false)
  • 发送AJAX_SUCCESSsuccess = true(其他设置为false)
  • error = true 发送AJAX_FAIL 时(其他设置为false)

所以当isLoadingtrue 更改为false 并且success 更改为falsetrue 时,我想将state.open 更改为false。

我不知道如何在不搞乱状态的情况下做到这一点。

编辑:

这是我的 sagas 代码,用于处理事件:

function* handleAjaxRequest(action) {
    try {
        yield call(api.doRequest);
        yield put({type: "AJAX_SUCCESS"});
    } catch (e) {
        yield put({type: "AJAX_FAILED"});
    }
}

export default function* () {
    yield [
        takeEvery("AJAX_REQUESTED", handleAjaxRequest),
    ]
}

【问题讨论】:

    标签: reactjs redux react-redux material-ui


    【解决方案1】:

    您可以使用componentWillReceiveProps(),一旦您的组件获得 redux 属性/状态更新,就会调用它。在那里你可以对 redux 状态变化做出反应并相应地设置你的本地组件状态。

    在你的例子中是:

    componentWillReceiveProps(nextProps) {
      if (nextProps.loading !== this.props.loading &&
          nextProps.success !== this.props.success &&
          !nextProps.loading && nextprops.success) {
        this.setState({ open: false });
      }
    }
    

    这正是您定义的想要的行为。 Imo 您还应该处理其他情况并更动态地设置 state.open ,但这超出了问题的范围。

    参考这里:https://facebook.github.io/react/docs/react-component.html#componentwillreceiveprops

    【讨论】:

    • 使用 React 17.x.x 这将被弃用,但它可以用作 UNSAFE_componentWillReceiveProps(nextProps) { ... }
    猜你喜欢
    • 1970-01-01
    • 2016-11-11
    • 2018-06-05
    • 2017-01-12
    • 2020-11-24
    • 2016-10-02
    • 1970-01-01
    • 1970-01-01
    • 2018-09-28
    相关资源
    最近更新 更多