Как объединить снэк-бар Material-UI и входные компоненты в реакции? - PullRequest
0 голосов
/ 18 ноября 2018

Я использую Material-UI компоненты для создания моего сайта. У меня есть компонент заголовка с полем поиска, который использует mui InputBase под капотом. Когда пользователь вводит пустой ввод (то есть он ничего не вводит и просто нажимает ввод), я хочу отобразить mui Snackbar , который будет предупреждать пользователя о том, что ввод значимого значения не был введен.

Я не могу заставить комбинацию двух компонентов работать вместе. Кроме того, поскольку состояние поля поиска на самом деле не меняется, когда пользователь ничего не вводит, оно не перезагружается, поэтому, если пользователь нажимает кнопку 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.log(`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;

1 Ответ

0 голосов
/ 19 ноября 2018

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

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>
  );
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...