Redux Form Material UI:选择嵌套列表不起作用
Posted
技术标签:
【中文标题】Redux Form Material UI:选择嵌套列表不起作用【英文标题】:Redux Form Material UI: Select with Nested Lists not working 【发布时间】:2019-10-04 11:53:17 【问题描述】:我有一种情况需要显示项目的分组列表:https://v0.material-ui.com/#/components/list(转到嵌套列表)
redux-form Select 字段能否使用 <ListItem />
而不是 <MenuItem />
的选项?
我无法从嵌套下拉列表中选择任何项目。 Redux 的 onChange
回调没有启动。
代码如下: 表格:
<form>
<Field
name="camops"
normalize=normalizeMultipleSelectValues
component=MySelectFormField
floatingLabelText="Item(s)"
fullWidth
multiple
/>
</form>
组件MySelectFormField
:
import get from 'lodash/get';
import groupBy from 'lodash/groupBy';
import isEmpty from 'lodash/isEmpty';
import List, ListItem from 'material-ui/List';
import PropTypes from 'prop-types';
import React, Component from 'react';
import Typography from '@material-ui/core/Typography';
import SelectFormField from './common/SelectFormField';
class MySelectFormField extends Component
static propTypes =
bookingId: PropTypes.string,
multiple: PropTypes.bool,
disabled: PropTypes.bool,
input: PropTypes.object.isRequired,
camops: PropTypes.array,
camopsFetch: PropTypes.func.isRequired,
;
static defaultProps =
bookingId: null,
multiple: false,
disabled: false,
camops: [],
;
componentDidMount()
const camopsFetch = this.props;
camopsFetch();
renderListItems(data)
let listItems = null;
if (!isEmpty(data))
listItems = Object.keys(data).map(region =>
const count = data[region].length;
const nestedItems = this.renderNestedListItem(data[region]);
const primaryText = (
<Typography variant="h6" component="div">
`$region($count)`
</Typography>
);
return (
<ListItem
key=region
primaryText=primaryText
initiallyOpen=true
primaryTogglesNestedList=true
nestedItems=nestedItems
/>
);
);
return listItems;
renderNestedListItem(data)
let nestedList = null;
if (!isEmpty(data))
nestedList = data.map(camop =>
const uuid = get(camop, 'uuid', '');
const fullName = get(camop, 'full_name', '');
const email = get(camop, 'email', '');
const label = `$fullName ($email)`.trim();
let checked = false;
if (this.props.multiple)
checked = this.props.input.value.indexOf(uuid) > -1;
return <ListItem key=uuid value=uuid primaryText=label checked=checked />;
);
return nestedList;
render()
const bookingId, disabled, camops, camopsFetch, ...restProps = this.props;
const hasCamOps = !!camops && !!camops.length;
const enabled = !disabled && hasCamOps;
let groupedCamops = groupBy(camops, 'region');
// Sort the grouped camops
groupedCamops = Object.keys(groupedCamops)
.sort()
.reduce((r, k) => Object.assign(r, [k]: groupedCamops[k] ), );
const listItems = this.renderListItems(groupedCamops);
return (
<SelectFormField ...restProps disabled=!enabled>
<List style= maxHeight: '100%', overflow: 'auto' >listItems</List>
</SelectFormField>
);
export default MySelectFormField;
组件SelectFormField
:
import React, Component from 'react';
import PropTypes from 'prop-types';
import SelectField from 'redux-form-material-ui';
class SelectFormField extends Component
static propTypes =
children: PropTypes.node,
helpText: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
meta: PropTypes.object.isRequired,
input: PropTypes.object.isRequired,
isRequired: PropTypes.bool,
;
static defaultProps =
children: null,
helpText: null,
isRequired: false,
;
render()
const children, helpText, isRequired, ...restProps = this.props;
return (
<div className="select-form-field">
<SelectField ...restProps>children</SelectField>
!!isRequired && <span className="select-form-field__marker">* </span>
!!helpText && <div className="form-help-text">helpText</div>
</div>
);
export default SelectFormField;
【问题讨论】:
【参考方案1】:我使用名为 renderSelectField
的自定义选择字段创建了一个 redux-form
字段。
select中的options项是普通的html
option
:
import Field, reduxForm from 'redux-form'
<Field name="type" component=renderSelectField label="Type">
materialTypes.map(materialType =>
return (
<option key=materialType value=materialType>
materialType
</option>
)
)
</Field>
renderSelectField
:
import SelectField from 'material-ui/Select'
import FormControl from 'material-ui/Form/FormControl'
import InputLabel from 'material-ui/Input/InputLabel'
import FormHelperText from 'material-ui'
const renderSelectField = (
input,
label,
meta: touched, error ,
children,
...custom
) => (
<FormControl className="admin-form-field">
<InputLabel error=touched && error>label</InputLabel>
<SelectField
floatingLabelText=label
error=touched && error
...input
children=children
...custom
/>
<FormHelperText error=touched && error>error</FormHelperText>
</FormControl>
)
不需要redux-form-material-ui
。只是redux-form
和material-ui
。
希望对您有所帮助。
【讨论】:
以上是关于Redux Form Material UI:选择嵌套列表不起作用的主要内容,如果未能解决你的问题,请参考以下文章
Material-UI 和 Redux-form,点击 select 时重新渲染选项,如何防止?
使用material-ui为redux-form设置initialValues无效
使用 Redux/React 的 Material UI TablePagination 句柄
反应 |还原形式 |材料-ui |如何将 DatePicker 与我的表单结合使用