JSX保存到状态时,Select MenuItem不显示

时间:2018-06-25 22:55:33

标签: reactjs material-ui

在此示例中进行工作:https://material-ui.com/demos/selects/,我收到一些奇怪的结果。具体来说,当我从下拉菜单中选择一个项目时,this.props.value会正常更新...但是不会显示MenuItem。

如果我将<FormControl>标签直接放置在render中,它可以正常工作。如果我输入一个变量,则使用setState并将其插入渲染器中……这是行不通的。

示例:

import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import InputLabel from '@material-ui/core/InputLabel';
import MenuItem from '@material-ui/core/MenuItem';
import FormControl from '@material-ui/core/FormControl';
import Select from '@material-ui/core/Select';

const styles = theme => ({
    root: {
        display: 'flex',
        flexWrap: 'wrap',
    },
    formControl: {
        margin: theme.spacing.unit,
        minWidth: 120,
    },
    selectEmpty: {
        marginTop: theme.spacing.unit * 2,
    },
});

class Question extends React.Component {
    state = {
        age: '',
        age2: '',
        slct: ''
    };

    componentDidMount() {
        const { classes } = this.props;
        var mySelect =
            <FormControl className={classes.formControl}>
                <InputLabel htmlFor="age-simple">Age</InputLabel>
                <Select
                    value={this.state.age}
                    onChange={this.handleChange}
                    inputProps={{
                        name: 'age',
                        id: 'age-simple',
                    }}
                >
                    <MenuItem value="">
                        <em>None</em>
                    </MenuItem>
                    <MenuItem value={10}>Ten</MenuItem>
                    <MenuItem value={20}>Twenty</MenuItem>
                    <MenuItem value={30}>Thirty</MenuItem>
                </Select>
            </FormControl>
        this.setState({ slct: mySelect });
    }

    handleChange = event => {
        this.setState({ [event.target.name]: event.target.value });
    };


    render() {
        const { classes } = this.props;
        return (
            <div>
                {this.state.slct}
                <p>Value:</p>{this.state.age}

                <FormControl className={classes.formControl}>
                    <InputLabel htmlFor="age-simple2">Age</InputLabel>
                    <Select
                        value={this.state.age2}
                        onChange={this.handleChange}
                        inputProps={{
                            name: 'age2',
                            id: 'age-simple2',
                        }}
                    >
                        <MenuItem value="">
                            <em>None</em>
                        </MenuItem>
                        <MenuItem value={10}>Ten</MenuItem>
                        <MenuItem value={20}>Twenty</MenuItem>
                        <MenuItem value={30}>Thirty</MenuItem>
                    </Select>
                </FormControl>
                <p>Value:</p>{this.state.age2}

            </div>
        );
    }
}

export default withStyles(styles)(Question);

根据我在下拉菜单中选择的答案,您可以看到“值”如何正确更新,但是在视觉上,MenuItem标签从不会出现来自状态的菜单项: enter image description here

帮助?

(仅供参考:这些物品在父母的<form>中。)

2 个答案:

答案 0 :(得分:1)

它必须是用于渲染的函数或数组。为了使您的代码正常工作,应为:

  state = {
    slct: <FormControl>...</FormControl>
  }

  slctRenderer = () => this.state.slct;

  render() {
    return (
      <div>
        {this.slctRenderer()}
      </div>
    );
  }

答案 1 :(得分:1)

使用来自@Jee Mok的信息...它可能作为函数工作的想法(即使其他项目似乎无关紧要),使我尝试对初始代码进行以下更改:

添加了此功能:

selectRenderer() {
        const { classes } = this.props;
        return (
        <FormControl className={classes.formControl}>
            <InputLabel htmlFor="age-simple">Age</InputLabel>
            <Select
                value={this.state.age}
                onChange={this.handleChange}
                inputProps={{
                    name: 'age',
                    id: 'age-simple',
                }}
            >
                <MenuItem value="">
                    <em>None</em>
                </MenuItem>
                <MenuItem value={10}>Ten</MenuItem>
                <MenuItem value={20}>Twenty</MenuItem>
                <MenuItem value={30}>Thirty</MenuItem>
            </Select>
        </FormControl>
        );
    };

然后在组件的render函数中,将其命名为:

render() {
    return (
        <div>
            {this.selectRenderer()}
            <p>Value:</p>{this.state.age}
        </div>
    );
}

这有效。 (因此,我会在两天内将其标记为已回答)

但是,我很好奇,为什么需要将JSX的这一特定块作为一个函数引入而其他JSX的其他块却不需要。 (具体来说,像我在OP中一样,将Material-ui文本字段分配给state效果很好),我希望能够一次(最好是componentDidMount生命周期的一部分)提出这个问题,并且然后以某种方式将内置问题传递给render函数。状态似乎是做到这一点的方法,但是由于某些原因,我无法使用Select / MenuItems。