Как объединить закуску Material-UI и компоненты ввода в React?

Я использую компоненты Материал-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;
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
1 991
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, что хороший способ добиться того, чего Вы хотите, - это добавить еще одно свойство состояния под названием 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>
  );
}

Надеюсь, что мой ответ будет полезен :)

Другие вопросы по теме