Materia UI 简单 select 不节省 selection

Materia UI simple select not saving selection

我在 Material UI 的对话框表单中有一个简单的 select 字段。表单使用状态将值保存在状态 onChange 中。我的州代码如下:

    const [planner, setPlanner] = useState({
  name: '',
  title: '1',
 
});

const { title, name } = planner;
const onChange = (e) => {
  setPlanner({ ...planner, [e.target.id]: e.target.value });

我的表单代码如下:

<Dialog
      open={open}
      onClose={handleClose}
      aria-labelledby='form-dialog-title'
    >
      <DialogTitle id='form-dialog-title'>Add New Planner</DialogTitle>
      <DialogContent>
        <DialogContentText>
          some text
        </DialogContentText>
        <FormControl className={classes.formControl}>
          <InputLabel id='title-label'>Title</InputLabel>
          <Select labelId='title' id='title' value={title} onChange={onChange}>
            <MenuItem value={10}>Mr</MenuItem>
            <MenuItem value={20}>Mrs</MenuItem>
          </Select>
        </FormControl>

        <TextField
          margin='dense'
          id='name'
          label='Name'
          type='text'
          value={name}
          onChange={onChange}
          fullWidth
          autoComplete='name'
        />
      </DialogContent>
      <DialogActions>
        <Button onClick={handleClose} color='primary'>
          Cancel
        </Button>
        <Button onClick={onSubmit} color='primary'>
          Add Planner
        </Button>
      </DialogActions>
    </Dialog>

感谢您的帮助! 完整页面代码如下:使用了redux state manager和useEffect、useState Hooks。除此之外,表单非常简单,除了这个标题下拉列表外,其他一切都很好。

import React, { useState, useEffect } from 'react';
import TextField from '@material-ui/core/TextField';
import Dialog from '@material-ui/core/Dialog';
import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@material-ui/core/DialogContent';
import DialogContentText from '@material-ui/core/DialogContentText';
import DialogTitle from '@material-ui/core/DialogTitle';
import Button from '@material-ui/core/Button';
import { makeStyles } from '@material-ui/core/styles';
import {
  addPlanner,
  clearErrors,
  clearAdd,
} from '../../actions/plannerActions';
import { setAlert } from '../../actions/alertActions';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import Select from '@material-ui/core/Select';
import MenuItem from '@material-ui/core/MenuItem';
import InputLabel from '@material-ui/core/InputLabel';
import FormControl from '@material-ui/core/FormControl';

const useStyles = makeStyles((theme) => ({
  root: {
    '& > *': {
      margin: theme.spacing(2),
    },
  },
  text: {
    textAlign: 'center',
  },
  appBarSpacer: theme.mixins.toolbar,
  content: {
    flexGrow: 1,
    overflow: 'auto',
  },
  container: {
    paddingTop: theme.spacing(10),
    paddingBottom: theme.spacing(20),
  },
  textfield: {
    width: '100%',
    border: 0,
  },
  formControl: {
    minWidth: 120,
  },
}));
const PlannerForm = ({
  addPlanner,
  error,
  clearErrors,
  setAlert,
  open,
  handleClose,
  add,
}) => {
  // const [open, setOpen] = React.useState(false);
  const classes = useStyles();
  const [planner, setPlanner] = useState({
    name: '',
    email: '',
    title: '',
    company: '',
    phone: '',
    comments: '',
    password: '123123',
  });

  const { title, name, email, company, phone, comments } = planner;
  const onChange = (e) => {
    setPlanner({ ...planner, [e.target.id]: e.target.value });
  };
  const clearForm = () => {
    setPlanner({
      name: '',
      email: '',
      title: '',
      company: '',
      phone: '',
      comments: '',
      password: '123123',
    });
    clearAdd();
  };

  React.useEffect(() => {
    if (error) {
      setAlert(error.errors[0].msg, 'error');
    } else if (add) {
      setAlert('Planner Added', 'success');
      clearForm();
    }
  }, [error, add]);

  const onSubmit = async (e) => {
    e.preventDefault();

    addPlanner(planner);
  };

  return (
    <Dialog
      open={open}
      onClose={handleClose}
      aria-labelledby='form-dialog-title'
    >
      <DialogTitle id='form-dialog-title'>Add New Planner</DialogTitle>
      <DialogContent>
        <DialogContentText>
          To add a new planner insert their info and they will receive an email
          to activate their account, set a new password and login.
        </DialogContentText>
        <FormControl className={classes.formControl}>
          <InputLabel id='title-label'>Title</InputLabel>
          <Select labelId='title' id='title' value={title} onChange={onChange}>
            <MenuItem value={10}>Mr</MenuItem>
            <MenuItem value={20}>Mrs</MenuItem>
          </Select>
        </FormControl>

        <TextField
          margin='dense'
          id='name'
          label='Name'
          type='text'
          value={name}
          onChange={onChange}
          fullWidth
          autoComplete='name'
        />

        <TextField
          margin='dense'
          id='company'
          label='Company'
          type='text'
          value={company}
          onChange={onChange}
          fullWidth
          autoComplete='company'
        />
        <TextField
          margin='dense'
          id='email'
          label='Email Address'
          type='email'
          value={email}
          onChange={onChange}
          fullWidth
          autoComplete='email'
        />
        <TextField
          margin='dense'
          id='phone'
          label='Phone Number'
          type='tel'
          value={phone}
          onChange={onChange}
          fullWidth
          autoComplete='tel'
        />
        <TextField
          placeholder='Additional Comments'
          multiline
          rows={4}
          margin='dense'
          id='comments'
          value={comments}
          onChange={onChange}
          fullWidth
        />
      </DialogContent>
      <DialogActions>
        <Button onClick={handleClose} color='primary'>
          Cancel
        </Button>
        <Button onClick={onSubmit} color='primary'>
          Add Planner
        </Button>
      </DialogActions>
    </Dialog>
  );
};

PlannerForm.propTypes = {
  addPlanner: PropTypes.func.isRequired,
  error: PropTypes.object,
  setAlert: PropTypes.func.isRequired,
  clearErrors: PropTypes.func.isRequired,
  open: PropTypes.bool.isRequired,
  handleClose: PropTypes.func.isRequired,
  add: PropTypes.bool.isRequired,
};

const mapStateToProps = (state) => ({
  isAuthenticated: state.planners.isAuthenticated,
  error: state.planners.error,
  add: state.planners.add,
});

export default connect(mapStateToProps, {
  addPlanner,
  clearErrors,
  setAlert,
})(PlannerForm);

docs

The id of the wrapper element or the select element when native.

ID 应用于包装器 div 而不是 select。要使其工作,请使用 native prop to Select 并将其设置为 true.

Working demo

代码片段

export default function FormDialog() {
  const [planner, setPlanner] = useState({
    name: "",
    title: "10"
  });

  const { title, name } = planner;
  const onChange = (e, b) => {
    const target = e.target;
    setPlanner(prev => ({ ...prev, [target.id]: target.value }));
  };
  return (
    <div>
      <Dialog
        open={true}
        // onClose={handleClose}
        aria-labelledby="form-dialog-title"
      >
        <DialogTitle id="form-dialog-title">Add New Planner</DialogTitle>
        <DialogContent>
          <DialogContentText>some text</DialogContentText>
          <FormControl>
            <InputLabel id="title-label">Title</InputLabel>
            <Select
              native
              labelId="title"
              id="title"
              value={title}
              onChange={onChange}
            >
              <option value={10}>Mr</option>
              <option value={20}>Mrs</option>
            </Select>
          </FormControl>

          <TextField
            margin="dense"
            id="name"
            label="Name"
            type="text"
            value={name}
            onChange={onChange}
            fullWidth
            autoComplete="name"
          />
        </DialogContent>
        <DialogActions>
          <Button color="primary">Cancel</Button>
          <Button color="primary">Add Planner</Button>
        </DialogActions>
      </Dialog>
    </div>
  );
}

我通过向 Select 添加名称属性解决了这个问题。出于某种原因 event.target.id 不工作(可能与其他包装组件冲突)

这是一个working code