Я все еще новичок в React, но я пытаюсь создать форму для веб-приложения управления проектами.
Я использую Material-UI.Я основал свой код на одном из примеров компонентов блока выбора из документов material-ui.
Я только недавно выяснил, как работают React-Hooks, и в примере использовалась эта функция.
Я пытаюсь изменить form.js, чтобы обновить окно множественного выбора, основываясь на состоянии App.js через реквизиты, вместо того, чтобы полагаться на хуки функциональных компонентов.
Кажется,работать, когда я оставляю ловушки на месте для personName, но как только я пытаюсь изменить его на что-то вроде props.accountSelected, я начинаю видеть ошибки, и несколько выбранных чипов больше не отображаются.
App.js:
import React, { Component } from 'react';
import './App.css';
import Form from './Form'
class App extends Component {
constructor() {
super();
this.state = {
projectName: '',
accountField: {
selected: {value: 'jacks', label: 'Jacks'},
options:[
{value: 'walmart', label: 'Walmart'},
{value: 'zellers', label: 'Zellers'},
{value: 'partyplace', label: 'Party Place'},
{value: 'majorbank', label: 'Major bank'}
]
}
}
}
setAccountsSelected(selected) {
console.log('>> [App.js] (setAccountsSelected) ',selected)
}
render() {
return (
<div className="App">
<Form
accountFieldoptions={this.state.accountField.options}
setAccountsSelected={this.setAccountsSelected}
accountSelected={this.state.accountField.selected}
/>
</div>
);
}
}
export default App;
Form.js (работает, но выбранные фишки больше не отображаются)
import React from 'react';
//import Select from 'react-select'; // https://github.com/JedWatson/react-select
import { makeStyles, useTheme } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';
import Input from '@material-ui/core/Input';
import InputLabel from '@material-ui/core/InputLabel';
import MenuItem from '@material-ui/core/MenuItem';
import FormControl from '@material-ui/core/FormControl';
import TextField from '@material-ui/core/TextField';
import Select from '@material-ui/core/Select';
import Chip from '@material-ui/core/Chip';
const useStyles = makeStyles(theme => ({
root: {
display: 'flex',
flexWrap: 'wrap',
},
formControl: {
margin: theme.spacing(1),
minWidth: 120,
maxWidth: 300,
},
chips: {
display: 'flex',
flexWrap: 'wrap',
},
chip: {
margin: 2,
},
noLabel: {
marginTop: theme.spacing(3),
},
}));
const ITEM_HEIGHT = 48;
const ITEM_PADDING_TOP = 8;
const MenuProps = {
PaperProps: {
style: {
maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
width: 250,
},
},
};
let names = [
'Oliver Hansen',
'Van Henry',
'April Tucker',
'Ralph Hubbard',
'Omar Alexander',
'Carlos Abbott',
'Miriam Wagner',
'Bradley Wilkerson',
'Virginia Andrews',
'Kelly Snyder',
];
function getStyles(name, personName, theme) {
return {
fontWeight:
personName.indexOf(name) === -1
? theme.typography.fontWeightRegular
: theme.typography.fontWeightMedium,
};
}
export default function Form(props) {
console.log('>> [Form.js] props = ',props)
const classes = useStyles();
const theme = useTheme();
names = [...props.accountFieldoptions];
console.log('>> [Form.js] names = ', names)
const [personName, setPersonName] = React.useState([]);
function handleChange(event) {
//setPersonName(event.target.value);
props.setAccountsSelected(event.target.value);
}
// function handleChangeMultiple(event) {
// const { options } = event.target;
// const value = [];
// for (let i = 0, l = options.length; i < l; i += 1) {
// if (options[i].selected) {
// value.push(options[i].value);
// }
// }
// setPersonName(value);
// }
return (
<div className={classes.root}>
<FormControl className={classes.formControl}>
<InputLabel htmlFor="select-multiple-accounts">Account</InputLabel>
<Select
multiple
value={personName}
onChange={handleChange}
input={<Input id="select-multiple-accounts" />}
renderValue={selected => (
<div className={classes.chips}>
{selected.map(value => (
<Chip key={value} label={value} className={classes.chip} />
))}
</div>
)}
MenuProps={MenuProps}
>
{names.map(name => (
<MenuItem key={name.label} value={name.label} style={getStyles(name.label, personName, theme)}>
{name.label}
</MenuItem>
))}
</Select>
</FormControl>
</div>
);
}
Form.js (выдает ошибку: TypeError: personName.indexOf не является функцией getStyles src/Form.js:62)
import React from 'react';
//import Select from 'react-select'; // https://github.com/JedWatson/react-select
import { makeStyles, useTheme } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';
import Input from '@material-ui/core/Input';
import InputLabel from '@material-ui/core/InputLabel';
import MenuItem from '@material-ui/core/MenuItem';
import FormControl from '@material-ui/core/FormControl';
import TextField from '@material-ui/core/TextField';
import Select from '@material-ui/core/Select';
import Chip from '@material-ui/core/Chip';
const useStyles = makeStyles(theme => ({
root: {
display: 'flex',
flexWrap: 'wrap',
},
formControl: {
margin: theme.spacing(1),
minWidth: 120,
maxWidth: 300,
},
chips: {
display: 'flex',
flexWrap: 'wrap',
},
chip: {
margin: 2,
},
noLabel: {
marginTop: theme.spacing(3),
},
}));
const ITEM_HEIGHT = 48;
const ITEM_PADDING_TOP = 8;
const MenuProps = {
PaperProps: {
style: {
maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
width: 250,
},
},
};
let names = [
'Oliver Hansen',
'Van Henry',
'April Tucker',
'Ralph Hubbard',
'Omar Alexander',
'Carlos Abbott',
'Miriam Wagner',
'Bradley Wilkerson',
'Virginia Andrews',
'Kelly Snyder',
];
function getStyles(name, personName, theme) {
return {
fontWeight:
personName.indexOf(name) === -1
? theme.typography.fontWeightRegular
: theme.typography.fontWeightMedium,
};
}
export default function Form(props) {
console.log('>> [Form.js] props = ',props)
const classes = useStyles();
const theme = useTheme();
names = [...props.accountFieldoptions];
console.log('>> [Form.js] names = ', names)
const [personName, setPersonName] = React.useState([]);
function handleChange(event) {
//setPersonName(event.target.value);
props.setAccountsSelected(event.target.value);
}
// function handleChangeMultiple(event) {
// const { options } = event.target;
// const value = [];
// for (let i = 0, l = options.length; i < l; i += 1) {
// if (options[i].selected) {
// value.push(options[i].value);
// }
// }
// setPersonName(value);
// }
return (
<div className={classes.root}>
<FormControl className={classes.formControl}>
<InputLabel htmlFor="select-multiple-accounts">Account</InputLabel>
<Select
multiple
value={props.accountSelected}
onChange={handleChange}
input={<Input id="select-multiple-accounts" />}
renderValue={selected => (
<div className={classes.chips}>
{selected.map(value => (
<Chip key={value} label={value} className={classes.chip} />
))}
</div>
)}
MenuProps={MenuProps}
>
{names.map(name => (
<MenuItem key={name.label} value={name.label} style={getStyles(name.label, props.accountSelected, theme)}>
{name.label}
</MenuItem>
))}
</Select>
</FormControl>
</div>
);
}
Исходный пример Я основал свой код на:
https://material -ui.com / components / selects /
import React from 'react';
import clsx from 'clsx';
import { makeStyles, useTheme } from '@material-ui/core/styles';
import Input from '@material-ui/core/Input';
import InputLabel from '@material-ui/core/InputLabel';
import MenuItem from '@material-ui/core/MenuItem';
import FormControl from '@material-ui/core/FormControl';
import ListItemText from '@material-ui/core/ListItemText';
import Select from '@material-ui/core/Select';
import Checkbox from '@material-ui/core/Checkbox';
import Chip from '@material-ui/core/Chip';
const useStyles = makeStyles(theme => ({
root: {
display: 'flex',
flexWrap: 'wrap',
},
formControl: {
margin: theme.spacing(1),
minWidth: 120,
maxWidth: 300,
},
chips: {
display: 'flex',
flexWrap: 'wrap',
},
chip: {
margin: 2,
},
noLabel: {
marginTop: theme.spacing(3),
},
}));
const ITEM_HEIGHT = 48;
const ITEM_PADDING_TOP = 8;
const MenuProps = {
PaperProps: {
style: {
maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
width: 250,
},
},
};
const names = [
'Oliver Hansen',
'Van Henry',
'April Tucker',
'Ralph Hubbard',
'Omar Alexander',
'Carlos Abbott',
'Miriam Wagner',
'Bradley Wilkerson',
'Virginia Andrews',
'Kelly Snyder',
];
function getStyles(name, personName, theme) {
return {
fontWeight:
personName.indexOf(name) === -1
? theme.typography.fontWeightRegular
: theme.typography.fontWeightMedium,
};
}
export default function MultipleSelect() {
const classes = useStyles();
const theme = useTheme();
const [personName, setPersonName] = React.useState([]);
function handleChange(event) {
setPersonName(event.target.value);
}
function handleChangeMultiple(event) {
const { options } = event.target;
const value = [];
for (let i = 0, l = options.length; i < l; i += 1) {
if (options[i].selected) {
value.push(options[i].value);
}
}
setPersonName(value);
}
return (
<div className={classes.root}>
<FormControl className={classes.formControl}>
<InputLabel htmlFor="select-multiple">Name</InputLabel>
<Select
multiple
value={personName}
onChange={handleChange}
input={<Input id="select-multiple" />}
MenuProps={MenuProps}
>
{names.map(name => (
<MenuItem key={name} value={name} style={getStyles(name, personName, theme)}>
{name}
</MenuItem>
))}
</Select>
</FormControl>
<FormControl className={classes.formControl}>
<InputLabel htmlFor="select-multiple-checkbox">Tag</InputLabel>
<Select
multiple
value={personName}
onChange={handleChange}
input={<Input id="select-multiple-checkbox" />}
renderValue={selected => selected.join(', ')}
MenuProps={MenuProps}
>
{names.map(name => (
<MenuItem key={name} value={name}>
<Checkbox checked={personName.indexOf(name) > -1} />
<ListItemText primary={name} />
</MenuItem>
))}
</Select>
</FormControl>
<FormControl className={classes.formControl}>
<InputLabel htmlFor="select-multiple-chip">Chip</InputLabel>
<Select
multiple
value={personName}
onChange={handleChange}
input={<Input id="select-multiple-chip" />}
renderValue={selected => (
<div className={classes.chips}>
{selected.map(value => (
<Chip key={value} label={value} className={classes.chip} />
))}
</div>
)}
MenuProps={MenuProps}
>
{names.map(name => (
<MenuItem key={name} value={name} style={getStyles(name, personName, theme)}>
{name}
</MenuItem>
))}
</Select>
</FormControl>
<FormControl className={clsx(classes.formControl, classes.noLabel)}>
<Select
multiple
displayEmpty
value={personName}
onChange={handleChange}
input={<Input id="select-multiple-placeholder" />}
renderValue={selected => {
if (selected.length === 0) {
return <em>Placeholder</em>;
}
return selected.join(', ');
}}
MenuProps={MenuProps}
>
<MenuItem disabled value="">
<em>Placeholder</em>
</MenuItem>
{names.map(name => (
<MenuItem key={name} value={name} style={getStyles(name, personName, theme)}>
{name}
</MenuItem>
))}
</Select>
</FormControl>
<FormControl className={classes.formControl}>
<InputLabel shrink htmlFor="select-multiple-native">
Native
</InputLabel>
<Select
multiple
native
value={personName}
onChange={handleChangeMultiple}
inputProps={{
id: 'select-multiple-native',
}}
>
{names.map(name => (
<option key={name} value={name}>
{name}
</option>
))}
</Select>
</FormControl>
</div>
);
}
Может кто-нибудь объяснить мне, что я делаю неправильно, и почему это работает с крючками, но не с реквизитом?