【发布时间】:2021-02-04 04:01:00
【问题描述】:
我正在制作一个反应应用程序并尝试在材料 ui 上重新创建此传输列表演示 - 使用旧的状态方法。但是我掉进了一些陷阱。
当前沙箱 https://codesandbox.io/s/morning-voice-qrym9?file=/src/TransferList.js
https://material-ui.com/components/transfer-list/ - 基于简单列表 - 我正在尝试将其重新创建为组件 - 遵循其余组件的构建方式 - 但函数和状态声明中的内容是造成错误的连锁反应
我当前的代码。
import React, { Component } from 'react'
import { withRouter } from 'react-router-dom';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import Grid from '@material-ui/core/Grid';
import List from '@material-ui/core/List';
import Card from '@material-ui/core/Card';
import CardHeader from '@material-ui/core/CardHeader';
import ListItem from '@material-ui/core/ListItem';
import ListItemText from '@material-ui/core/ListItemText';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import Checkbox from '@material-ui/core/Checkbox';
import Button from '@material-ui/core/Button';
import Divider from '@material-ui/core/Divider';
import './TransferList.scss';
class TransferList extends Component {
constructor(props, context) {
super(props, context);
this.state = {
checked: [],
left: [0, 1, 2, 3],
right: [4, 5, 6, 7]
};
}
not(a, b) {
//return a.filter((value) => b.indexOf(value) === -1);
}
intersection(a, b) {
//return a.filter((value) => b.indexOf(value) !== -1);
}
union(a, b) {
//return [...a, ...this.not(b, a)];
}
numberOfChecked(items) {
//return this.intersection(this.state.checked, items).length;
}
handleToggleAll(items) {
if (this.numberOfChecked(items) === items.length) {
this.state = {
checked: this.not(this.state.checked, items),
};
} else {
this.state = {
checked: this.union(this.state.checked, items),
};
}
};
handleCheckedRight() {
const leftChecked = this.intersection(this.state.checked, this.state.left);
this.state = {
right: this.state.right.concat(leftChecked),
left: this.not(this.state.left, leftChecked),
checked: this.not(this.state.checked, leftChecked),
};
};
handleCheckedLeft() {
const rightChecked = this.intersection(this.state.checked, this.state.right);
this.state = {
right: this.not(this.state.right, rightChecked),
left: this.state.left.concat(rightChecked),
checked: this.not(this.state.checked, rightChecked),
};
};
customList(title, items) {
return (
<Card>
<CardHeader
//className={classes.cardHeader}
avatar={
<Checkbox
onClick={this.handleToggleAll(items)}
checked={this.numberOfChecked(items) === items.length && items.length !== 0}
indeterminate={this.numberOfChecked(items) !== items.length && this.numberOfChecked(items) !== 0}
disabled={items.length === 0}
inputProps={{ 'aria-label': 'all items selected' }}
/>
}
title={title}
subheader={`${this.numberOfChecked(items)}/${items.length} selected`}
/>
<Divider />
<List
//className={classes.list}
dense
component="div"
role="list"
>
<ListItem />
</List>
</Card>
);
}
render() {
const leftChecked = this.intersection(this.state.checked, this.state.left);
const rightChecked = this.intersection(this.state.checked, this.state.right);
/*
const handleToggle = (value) => () => {
const currentIndex = checked.indexOf(value);
const newChecked = [...checked];
if (currentIndex === -1) {
newChecked.push(value);
} else {
newChecked.splice(currentIndex, 1);
}
setChecked(newChecked);
};
const numberOfChecked = (items) => this.intersection(checked, items).length;
const handleToggleAll = (items) => () => {
if (numberOfChecked(items) === items.length) {
setChecked(not(checked, items));
} else {
setChecked(union(checked, items));
}
};
const handleCheckedRight = () => {
setRight(right.concat(leftChecked));
setLeft(not(left, leftChecked));
setChecked(not(checked, leftChecked));
};
const handleCheckedLeft = () => {
setLeft(left.concat(rightChecked));
setRight(not(right, rightChecked));
setChecked(not(checked, rightChecked));
};
const customList = (title, items) => (
<Card>
<CardHeader
className={classes.cardHeader}
avatar={
<Checkbox
onClick={handleToggleAll(items)}
checked={numberOfChecked(items) === items.length && items.length !== 0}
indeterminate={numberOfChecked(items) !== items.length && numberOfChecked(items) !== 0}
disabled={items.length === 0}
inputProps={{ 'aria-label': 'all items selected' }}
/>
}
title={title}
subheader={`${numberOfChecked(items)}/${items.length} selected`}
/>
<Divider />
<List className={classes.list} dense component="div" role="list">
{items.map((value) => {
const labelId = `transfer-list-all-item-${value}-label`;
return (
<ListItem key={value} role="listitem" button onClick={handleToggle(value)}>
<ListItemIcon>
<Checkbox
checked={checked.indexOf(value) !== -1}
tabIndex={-1}
disableRipple
inputProps={{ 'aria-labelledby': labelId }}
/>
</ListItemIcon>
<ListItemText id={labelId} primary={`List item ${value + 1}`} />
</ListItem>
);
})}
<ListItem />
</List>
</Card>
);
*/
return (
<Grid container spacing={2} justify="center" alignItems="center">
<Grid item>{this.customList('Choices', this.state.left)}</Grid>
<Grid item>
<Grid container direction="column" alignItems="center">
<Button
variant="outlined"
size="small"
//className={classes.button}
onClick={this.handleCheckedRight}
disabled={leftChecked.length === 0}
aria-label="move selected right"
>
>
</Button>
<Button
variant="outlined"
size="small"
//className={classes.button}
onClick={this.handleCheckedLeft}
disabled={rightChecked.length === 0}
aria-label="move selected left"
>
<
</Button>
</Grid>
</Grid>
<Grid item>{this.customList('Chosen', this.state.right)}</Grid>
</Grid>
)
}
}
function mapStateToProps(state) {
return {
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({ }, dispatch);
}
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(TransferList))
////////
/*
export default function TransferList() {
const classes = useStyles();
const [checked, setChecked] = React.useState([]);
const [left, setLeft] = React.useState([0, 1, 2, 3]);
const [right, setRight] = React.useState([4, 5, 6, 7]);
const leftChecked = intersection(checked, left);
const rightChecked = intersection(checked, right);
const handleToggle = (value) => () => {
const currentIndex = checked.indexOf(value);
const newChecked = [...checked];
if (currentIndex === -1) {
newChecked.push(value);
} else {
newChecked.splice(currentIndex, 1);
}
setChecked(newChecked);
};
const numberOfChecked = (items) => intersection(checked, items).length;
const handleToggleAll = (items) => () => {
if (numberOfChecked(items) === items.length) {
setChecked(not(checked, items));
} else {
setChecked(union(checked, items));
}
};
const handleCheckedRight = () => {
setRight(right.concat(leftChecked));
setLeft(not(left, leftChecked));
setChecked(not(checked, leftChecked));
};
const handleCheckedLeft = () => {
setLeft(left.concat(rightChecked));
setRight(not(right, rightChecked));
setChecked(not(checked, rightChecked));
};
const customList = (title, items) => (
<Card>
<CardHeader
className={classes.cardHeader}
avatar={
<Checkbox
onClick={handleToggleAll(items)}
checked={numberOfChecked(items) === items.length && items.length !== 0}
indeterminate={numberOfChecked(items) !== items.length && numberOfChecked(items) !== 0}
disabled={items.length === 0}
inputProps={{ 'aria-label': 'all items selected' }}
/>
}
title={title}
subheader={`${numberOfChecked(items)}/${items.length} selected`}
/>
<Divider />
<List className={classes.list} dense component="div" role="list">
{items.map((value) => {
const labelId = `transfer-list-all-item-${value}-label`;
return (
<ListItem key={value} role="listitem" button onClick={handleToggle(value)}>
<ListItemIcon>
<Checkbox
checked={checked.indexOf(value) !== -1}
tabIndex={-1}
disableRipple
inputProps={{ 'aria-labelledby': labelId }}
/>
</ListItemIcon>
<ListItemText id={labelId} primary={`List item ${value + 1}`} />
</ListItem>
);
})}
<ListItem />
</List>
</Card>
);
*/
//////////
最新的沙盒工作 https://codesandbox.io/s/morning-voice-qrym9?file=/src/TransferList.js
【问题讨论】:
标签: javascript reactjs