Я использую компоненты Материал-UI для создания своего веб-сайта. У меня есть компонент заголовка с полем поиска, который использует mui InputBase под капотом. Когда пользователь вводит пустой ввод (то есть они ничего не вводят и просто нажимают кнопку ввода), я хочу отобразить mui Закусочная, который будет предупреждать пользователя о том, что не было введено значимого ввода.
Я не могу заставить комбинацию этих двух компонентов работать вместе. Кроме того, поскольку состояние поля поиска на самом деле не меняется, когда пользователь ничего не вводит, оно не перезагружается, поэтому, если пользователь несколько раз нажимает Enter, закусочная панель не появляется. Я использую this.forceUpdate();, но есть ли более элегантный способ реализовать такую логику?
Это мой код:
для поля ввода поиска:
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';
class AppSearchBarInput extends Component {
state = {
appId: ''
}
onChange = e => {
this.setState({ appId: e.target.value });
}
onKeyDown = e => {
const { appId } = this.state;
if (e.keyCode === constants.ENTER_KEY && appId !== '') {
this.props.getAppInfo({ appId });
this.setState({
appId: ''
});
}
this.props.history.push('/app/appInfo');
this.forceUpdate();
}
render() {
const { classes } = this.props;
const { appId } = this.state;
console.info(`appId from AppSearchInput=${appId === ''}`);
return (
<div>
<InputBase
placeholder = "Search…"
classes = {{
root: classes.inputRoot,
input: classes.inputInput,
}}
onChange = {this.onChange}
onKeyDown = {this.onKeyDown}
value = {this.state.appId} />
{ appId === '' ? <AppNotFound message = {constants.MESSAGES.APP_BLANK()}/> : ''}
</div>
)
}
}
AppSearchBarInput.propTypes = {
classes: PropTypes.object.isRequired
}
const AppSearchBarWithStyles = withStyles(AppSearchBarInputStyles)(AppSearchBarInput);
const AppSearchBarWithStylesWithRouter = withRouter(AppSearchBarWithStyles);
export default connect(null, { getAppInfo })(AppSearchBarWithStylesWithRouter);
для закусочной:
import React from 'react';
import Snackbar from '@material-ui/core/Snackbar';
import constants from '../../constants.js';
import SnackbarMessage from './SnackbarMessage.js';
class AppNotFound extends React.Component {
state = {
open: true,
};
handleClose = event => {
this.setState({ open: false });
};
render() {
const { message } = this.props;
return (
<Snackbar
anchorOrigin = {{
vertical: 'top',
horizontal: 'center',
}}
open = {this.state.open}
autoHideDuration = {6000}
onClose = {this.handleClose}
>
<SnackbarMessage
onClose = {this.handleClose}
variant = "warning"
message = {message}
/>
</Snackbar>
);
}
}
export default AppNotFound;



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я думаю, что хороший способ добиться того, чего Вы хотите, - это добавить еще одно свойство состояния под названием snackBarOpen, которое поможет Вам определить, ввел ли пользователь пустое значение или что-то значимое:
Компонент AppSearchBarInput
state = {
appId: '',
snackBarOpen: false
}
handleKeyDown = (e) => {
if (e.keyCode === 13 && e.target.value === '') {
this.setState({
appId: e.target.value,
snackBarOpen: true
});
} else {
this.setState({
appId: e.target.value
})
}
}
handleCloseSnackBar = () => {
this.setState({
snackBarOpen: false
});
}
А затем просто визуализируйте <AppNotFound /> в методе render () (по умолчанию он будет скрыт, потому что будет зависеть от open prop):
render() {
const { snackBarOpen } = this.state;
return(
<div>
/* <InputBase /> here */
<AppNotFound message = {/* Your message here */} open = {snackBarOpen} onClose = {this.handleCloseSnackBar} />
</div>
)
}
Компонент AppNotFound
Теперь вы можете удалить все методы и оставить только render (), который будет выглядеть следующим образом:
render() {
const { message, open, onClose } = this.props;
return (
<Snackbar
// ...
open = {open}
// ...
onClose = {onClose}
>
<SnackbarMessage
onClose = {onClose}
// ...
message = {message}
/>
</Snackbar>
);
}
Надеюсь, что мой ответ будет полезен :)