Javascript 在多个选择材质UI上反应渲染同级

Javascript 在多个选择材质UI上反应渲染同级,javascript,reactjs,material-ui,Javascript,Reactjs,Material Ui,这是我的问题: 我需要在React using material UI上创建一个多选(带有复选框),如下图所示: 我有如下数组中的数据 data = [ { id: 199, name: "Argentina", state: [ { name: "Buenos Aires", id: 1 }, { name: "Cordoba", id: 2 }, { name: "Chaco", id: 2 } ] }, {

这是我的问题: 我需要在React using material UI上创建一个多选(带有复选框),如下图所示:

我有如下数组中的数据

data = [
  {
    id: 199,
    name: "Argentina",
    state: [
      { name: "Buenos Aires", id: 1 },
      { name: "Cordoba", id: 2 },
      { name: "Chaco", id: 2 }
    ]
  },
  {
    id: 200,
    name: "USA",
    state: [
      { name: "California", id: 4 },
      { name: "Florida", id: 5 },
      { name: "Texas", id: 6 }
    ]
  }
]
太好了。一切似乎都要做2套地图,没有什么不寻常的。同时,我尝试以下方法:

<InputLabel htmlFor="grouped-select">Grouping</InputLabel>
<Select
  defaultValue={[]}
  id="grouped-select"
  onChange={handleChange}
  multiple
>
  <MenuItem value="">
    <Checkbox />
    <em>All</em>
  </MenuItem>
  {data.map(country => (
    <>
      <ListSubheader key={country.id}>{country.name}</ListSubheader>
      {country.state.map(state => (
        <MenuItem key={state.id} value={state.id}>
          <Checkbox />
          {state.name}
        </MenuItem>
      ))}
    </>
  ))}
</Select>
分组
全部的
{data.map(国家=>(
{country.name}
{country.state.map(state=>(
{state.name}
))}
))}
这样可以很好地渲染select,使其看起来很漂亮。但我的问题是(显然)材质不接受select中的React.Fragment(
)。同时,我无法生成Material UI在文档中通过数组循环指定的结构:

<ListSubheader>Parent 1</ListSubHeader>
<MenuItem key={state.id} value={state.id}>Child1</MenuItem>
<MenuItem key={state.id} value={state.id}>Child2</MenuItem>
<MenuItem key={state.id} value={state.id}>Child...n</MenuItem>

<ListSubheader>Parent 2</ListSubHeader>
<MenuItem key={state.id} value={state.id}>Child</MenuItem>
<MenuItem key={state.id} value={state.id}>Child...n</MenuItem>
Parent 1
孩子1
孩子2
孩子
家长2
小孩
孩子
如果我放置了
或其他元素而不是
,则onchange事件将停止工作

我还尝试对数组进行渲染,但效果不佳,因为第二个同级不是jsx,但我必须循环遍历数组

{data.map(country => [
    <ListSubheader key={country.id}>{country.name}</ListSubheader>
    {country.state.map(state => (
      <MenuItem key={state.id} value={state.id}>
        <Checkbox />
        {state.name}
      </MenuItem>
    ))}
  ])}
{data.map(国家=>[
{country.name}
{country.state.map(state=>(
{state.name}
))}
])}
我被封锁了,我不知道怎么解决。我想到了一个子组件,但在渲染它时,我也会遇到同样的问题

有办法解决吗

我留下了一个带有示例代码段的链接:


非常感谢。

我创建了一个与您的代码类似的示例。您可以在codesandbox中尝试。希望它能帮助您。
这是我的代码:

。。。
常量名称=[
“奥利弗·汉森”,
“范亨利”,
“四月塔克”,
“拉尔夫·哈伯德”,
“奥马尔·亚历山大”,
“卡洛斯·阿伯特”,
“米里亚姆·瓦格纳”,
“布拉德利·威尔克森”,
“弗吉尼亚·安德鲁斯”,
“凯利·斯奈德”
];
导出默认函数MultipleSelect(){
const classes=useStyles();
const[personName,setPersonName]=React.useState([]);
常量handleChangeMultiple=事件=>{
const{value}=event.target;
const allIndex=value.indexOf(“全部”);
如果(allIndex>-1){
常量值=[“全部”];
for(让名字的名字){
value.push(名称);
}
setPersonName(值);
}否则{
setPersonName([]);
}
};
返回(
标签
已选择。加入(“,”}
MenuProps={MenuProps}
>
-1} />
全部的
{names.map(name=>(
-1} />
))}
);

}
您可以检查此代码沙盒

从这个答案中您可以注意到,您总是可以创建元素,而不需要片段。因为片段只是数组的包装器。因为,材质中不需要碎片。您可以使用纯数组来渲染元素,而不是将其包装成片段


function makeItems(data) {
  const items = [];
  for (let country of data) {
    items.push(<ListSubheader key={country.id}>{country.name}</ListSubheader>);
    for (let state of country.state) {
      items.push(
        <MenuItem key={state.id} value={state.id}>
          <Checkbox />
          {state.name}
        </MenuItem>
      );
    }
  }
  return items;
}

函数makeItems(数据){
常量项=[];
对于(数据所在国){
items.push({country.name});
for(让国家/地区/州){
推(
{state.name}
);
}
}
退货项目;
}

您可以看到我是如何使用另一个函数将它们推入javascript数组,然后将它们呈现到树中的

我检查了您的代码并对其进行了一些更改。你可以在这里找到它:


尽管它现在完全可以工作,因为您必须使用useState定义状态,然后保存您的值。我在EventHandler中添加了console,让您了解如何解决您的问题

我改变了三个不同的方面:

  • 不要使用片段,而是将菜单项添加到数组中(
    menuItems
    ,在下面的示例中),然后渲染数组(与Dipesh Dulal的答案相同)
  • 改进复选框的行为。在原始代码中,复选框状态与
    Select
    是否考虑选择菜单项不同步。我已将复选框包装到一个自定义的
    MenuItemWithCheckbox
    组件中,该组件使用
    selected
    prop(即)控制复选框的
    选中状态
  • 修复选定值的外观。所选值的默认显示(不使用Select的
    renderValue
    prop时)使用作为显示文本。这意味着,如果菜单项的子项包含文本以外的内容,它将以奇怪的方式显示。通过引入自定义的
    MenuItemWithCheckbox
    组件来处理复选框显示,直接子项现在只包含文本,默认显示工作正常
以下是我修改后的沙盒版本中的代码:

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import InputLabel from "@material-ui/core/InputLabel";
import MenuItem from "@material-ui/core/MenuItem";
import ListSubheader from "@material-ui/core/ListSubheader";
import FormControl from "@material-ui/core/FormControl";
import Select from "@material-ui/core/Select";
import { Checkbox } from "@material-ui/core";

const useStyles = makeStyles(theme => ({
  formControl: {
    margin: theme.spacing(1),
    minWidth: 120
  }
}));

const data = [
  {
    id: 199,
    name: "Argentina",
    state: [
      { name: "Buenos Aires", id: 1 },
      { name: "Cordoba", id: 2 },
      { name: "Chaco", id: 3 }
    ]
  },
  {
    id: 200,
    name: "USA",
    state: [
      { name: "California", id: 4 },
      { name: "Florida", id: 5 },
      { name: "Texas", id: 6 }
    ]
  }
];

const handleChange = ev => {
  //console.log(ev);
};

const MenuItemWithCheckbox = React.forwardRef(function MenuItemWithCheckbox(
  { children, selected, em = false, ...other },
  ref
) {
  return (
    <MenuItem {...other} selected={selected} ref={ref}>
      <Checkbox checked={selected} />
      {em && <em>{children}</em>}
      {!em && children}
    </MenuItem>
  );
});

export default function GroupedSelect() {
  const classes = useStyles();
  const menuItems = [];
  menuItems.push(
    <MenuItemWithCheckbox key="" value="" em={true}>
      All
    </MenuItemWithCheckbox>
  );
  data.forEach(country => {
    menuItems.push(
      <ListSubheader key={country.id}>{country.name}</ListSubheader>
    );
    country.state.forEach(state => {
      menuItems.push(
        <MenuItemWithCheckbox key={state.id} value={state.id}>
          {state.name}
        </MenuItemWithCheckbox>
      );
    });
  });
  return (
    <div>
      <FormControl className={classes.formControl}>
        <InputLabel htmlFor="grouped-select">Grouping</InputLabel>
        <Select
          defaultValue={[]}
          id="grouped-select"
          onChange={handleChange}
          multiple
        >
          {menuItems}
        </Select>
      </FormControl>
    </div>
  );
}
从“React”导入React;
从“@material ui/core/styles”导入{makeStyles}”;
从“@material ui/core/InputLabel”导入InputLabel;
从“@material ui/core/MenuItem”导入菜单项;
从“@material ui/core/ListSubheader”导入列表子标题;
从“@material ui/core/FormControl”导入FormControl;
从“@material ui/core/Select”导入选择;
从“@material ui/core”导入{Checkbox}”;
const useStyles=makeStyles(主题=>({
表单控制:{
边距:主题。间距(1),
最小宽度:120
}
}));
常数数据=[
{
身份证号码:199,
名称:“阿根廷”,
声明:[
{姓名:“布宜诺斯艾利斯”,id:1},
{姓名:“科尔多瓦”,id:2},
{姓名:“查科”,身份证号码:3}
]
},
{
id:200,
名称:“美国”,
声明:[
{姓名:“加利福尼亚”,id:4},
{姓名:“佛罗里达”,身份证号码:5},
{姓名:“德克萨斯”,身份证号码:6}
]
}
];
常数handleChange=ev=>{
//控制台日志(ev);
};
const MenuItemWithCheckbox=React.forwardRef(函数MenuItemWithCheckbox(
{子项,选中,em=false,…其他},
裁判
) {