Я новичок в React и Redux и пытаюсь создать сайт.Я использую компоненты Material-UI.AppSearchBarInput
- это ввод в заголовке, где пользователи могут искать идентификатор (в коде обозначается appId
).Если appId
равно found
в базе данных, я хочу перенаправить на другую страницу (this.props.history.push('/app/appInfo');
).Если ввод пуст, тогда я отображаю снэк-бар (AppNotFound
) с предупреждающим сообщением, а также когда ввод отсутствует в базе данных.
В методе onKeyDown
я использую connect
для отправки действия, которое проверяет, существует ли идентификатор в базе данных (dispatch
вызывается из getAppInfo
с использованием redux-thunk
).Затем мне нужно немедленно получить новое состояние Redux через реквизит, чтобы решить, был ли идентификатор найден или нет, и в зависимости от этого я установил для свойства snackBarOpen
local state значение true или false.
Проблема в том, что я не могу получить обновленный реквизит в том же методе при вызове dispatch.Я мог бы использовать componentDidUpdate
, но тогда я не могу обновить локальное хранилище из него.Есть ли обходной путь для этой ситуации, использующий какой-либо метод жизненного цикла реакции или трюк с избыточностью?
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);