使用 react-redux 触发事件动作
Trigger an action on event with react-redux
我正在使用 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 构建如下:
isLoading = true
发送时AJAX_REQUESTED
(其他设置为false)
success = true
发送时AJAX_SUCCESS
(其他设置为false)
error = true
发送时AJAX_FAIL
(其他设置为false)
所以当 isLoading
从 true
更改为 false
并且 success
更改为 false
时,我想将 state.open
更改为 false至 true
.
我不知道如何在不扰乱状态的情况下做到这一点。
编辑:
这是我的传奇代码,用于处理事件:
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),
]
}
您可以利用 componentWillReceiveProps()
,一旦您的组件获得 redux property/state 更新,它就会被调用。在那里你可以对 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 / 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 构建如下:
isLoading = true
发送时AJAX_REQUESTED
(其他设置为false)success = true
发送时AJAX_SUCCESS
(其他设置为false)error = true
发送时AJAX_FAIL
(其他设置为false)
所以当 isLoading
从 true
更改为 false
并且 success
更改为 false
时,我想将 state.open
更改为 false至 true
.
我不知道如何在不扰乱状态的情况下做到这一点。
编辑:
这是我的传奇代码,用于处理事件:
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),
]
}
您可以利用 componentWillReceiveProps()
,一旦您的组件获得 redux property/state 更新,它就会被调用。在那里你可以对 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