[英]How to set react state with new props immediately after calling `dispatch` via react-redux connect?
我是React和Redux的新手,正在尝试建立一个网站。 我正在使用Material-UI组件。 AppSearchBarInput
是标题中的输入,用户可以在其中搜索ID(在代码中称为appId
)。 如果在数据库中found
了appId
,那么我想重定向到另一个页面( this.props.history.push('/app/appInfo');
)。 如果输入为空,则显示带警告消息的小吃栏( AppNotFound
),以及数据库中不存在输入时。
在onKeyDown
方法中,我使用connect
调度一个操作,该操作检查id是否存在于数据库中(使用redux-thunk
从getAppInfo
调用dispatch
)。 然后,我需要立即通过props获取新的Redux状态,以便确定是否找到了ID,并根据此ID将snackBarOpen
本地状态属性设置为true或false。
问题是调用调度时,我无法在同一方法中获得更新的道具。 我可以使用componentDidUpdate
但是无法从中更新本地存储。 对于这种情况,是否可以使用一些反应生命周期方法或redux技巧来解决?
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import InputBase from '@material-ui/core/InputBase';
import { withStyles } from '@material-ui/core/styles';
import { withRouter } from 'react-router-dom';
import { connect } from 'react-redux';
import { getAppInfo } from '../../actions/appActions.js';
import constants from '../../constants.js';
import { AppSearchBarInputStyles } from '../styles/Material-UI/muiStyles.js';
import AppNotFound from './AppNotFound.js';
import * as log from 'loglevel';
log.setLevel("debug")
class AppSearchBarInput extends Component {
state = {
appId: '',
snackBarOpen: false
}
onChange = e => {
this.setState({ appId: e.target.value });
}
onKeyDown = e => {
const { appId } = this.state;
if (e.keyCode === constants.ENTER_KEY) {
if (appId.trim() !== '') {
this.props.getAppInfo({ appId });
this.setState({
appId: ''
});
const { found } = this.props.app; // ! problem here !
if (found) {
this.props.history.push('/app/appInfo');
} else {
this.setState({
snackBarOpen: true
});
}
} else {
this.setState({
snackBarOpen: true
});
}
}
}
handleCloseSnackBar = () => {
this.setState({
snackBarOpen: false
});
}
render() {
const { classes } = this.props;
const { appId, snackBarOpen } = this.state;
const { found } = this.props.app;
let message = '';
if (!found) {
message = appId === '' ? constants.MESSAGES.APP_BLANK() : constants.MESSAGES.APP_NOT_FOUND(appId);
}
return (
<div>
<InputBase
placeholder="Search…"
classes={{
root: classes.inputRoot,
input: classes.inputInput,
}}
onChange={this.onChange}
onKeyDown={this.onKeyDown}
value={this.state.appId} />
<AppNotFound message={message}
open={snackBarOpen && !found}
onClose={this.handleCloseSnackBar}/>
</div>
)
}
}
AppSearchBarInput.propTypes = {
classes: PropTypes.object.isRequired
}
const mapStateToProps = state => ({
app: state.app.app
});
const AppSearchBarWithStyles = withStyles(AppSearchBarInputStyles)(AppSearchBarInput);
const AppSearchBarWithStylesWithRouter = withRouter(AppSearchBarWithStyles);
export default connect(mapStateToProps, { getAppInfo })(AppSearchBarWithStylesWithRouter);
从代码的外观来看,您没有调度方法。 如果确实获取了数据,那么您不会获得更新,因为withRouter
实际上阻止了shouldComponentUpdate。 如果要更新状态,则将connect
封装在withRouter
。
您还应该具有mapDispatchToProps函数。 像这样:
const mapDispatchToProps = dispatch => ({
makeDispatch: () => dispatch({ getAppInfo })
})
因此,代替:
const AppSearchBarWithStyles = withStyles(AppSearchBarInputStyles)(AppSearchBarInput);
const AppSearchBarWithStylesWithRouter = withRouter(AppSearchBarWithStyles);
export default connect(mapStateToProps, { getAppInfo })(AppSearchBarWithStylesWithRouter);
你应该有:
const AppSearchBarWithStyles = withStyles(AppSearchBarInputStyles)(AppSearchBarInput);
AppSearchBarWithStylesWithConnect = connect(mapStateToProps, mapDispatchToProps)(AppSearchBarWithStyles);
export default withRouter(AppSearchBarWithStylesWithConnect);
请查看以下内容: https : //reacttraining.com/react-router/core/api/withRouter
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.