javascript - 如何识别数组的某个对象id来改变同一对象中元素的状态?

标签 javascript reactjs material-ui

我试图在展开时识别数组中的特定面板,并能够将该面板的 id 连接到按钮,以及在没有展开面板或展开超过 1 个面板时禁用该按钮。无论出于何种原因,它根本不接受 id。另外,我在如何正确禁用该按钮方面遇到了问题。

export default class WorkoutList extends Component {
    constructor(props) {
        super(props);
        this.state = {
            workoutlist: [
                {
                    id: uuid.v4(),
                    name: 'Leg Day',
                    date: '08/09/19',
                    duration: 60,
                    exerciselist: [
                        {
                            id: uuid.v4(),
                            exerciseName: 'Squats',
                            numberOfSets: 3,
                            reps: 12,
                            weight: 135,
                        },
                        {
                            id: uuid.v4(),
                            exerciseName: 'Leg press',
                            numberOfSets: 3,
                            reps: 10,
                            weight: 150,
                        },
                        {
                            id: uuid.v4(),
                            exerciseName: 'Lunges',
                            numberOfSets: 4,
                            reps: 12,
                        },
                    ],
                    selected: false,
                },
                {
                    id: uuid.v4(),
                    name: 'Arm Day',
                    date: '08/10/19',
                    duration: 90,
                    exerciselist: [
                        {
                            id: uuid.v4(),
                            exerciseName: 'Bench Press',
                            numberOfSets: 5,
                            reps: 5,
                            weight: 225,
                        },
                        {
                            id: uuid.v4(),
                            exerciseName: 'Chest Flies',
                            numberOfSets: 3,
                            reps: 10,
                            weight: 50,
                        },
                        {
                            id: uuid.v4(),
                            exerciseName: 'Tricep Extensions',
                            numberOfSets: 4,
                            reps: 12,
                            weight: 70,
                        },
                    ],
                    selected: false,

                },
                {
                    id: uuid.v4(),
                    name: 'Running',
                    date: '08/11/19',
                    duration: 40,
                    exerciselist: [],
                    selected: false,

                },
            ],
            disabled: false
        }
        this.handleSelectedPanel = this.handleSelectedPanel.bind(this);
        this.handleButton = this.handleButton.bind(this);
    }

    handleSelectedPanel(id) {
        const { workoutlist } = this.state;
        this.setState({
            workoutlist: workoutlist.map(workout => {
                if (workout.id === id) {
                    workout.selected = !workout.selected
                }
                return workout;
            })
        })
    }

    handleButton(){
        const { workoutlist, disabled } = this.state;
        let count = 0;
        workoutlist.map((workout) => {
            if(workout.selected === true) {
                count = count + 1;
            }
            return count;
        })
        if (count !== 1) {
            this.setState({
                disabled: true
            })
        } else {
            this.setState({
                disabled: false
            })
        }
        return disabled;
    }

    render() {
        const { workoutlist } = this.state;
        return (
            <div>
                <CssBaseline />
                <ClientMenuBar title="My Workouts" />
                <div style={styles.workoutlist}>
                    <Paper style={styles.paper} elevation={0}>
                        {workoutlist.map((workout) => (
                            <WorkoutItem
                                key={workout.id}
                                workout={workout}
                                onSelectedPanel={this.handleSelectedPanel}
                            />
                        ))}
                    </Paper>
                    <Button
                        variant="contained"
                        color="primary"
                        size="small"
                        style={styles.button}
                        disabled={this.handleButton}
                    >
                        Start Workout
                    </Button>
                </div>
            </div>
        )
    }
}
export default class WorkoutItem extends Component {
    constructor(props){
        super(props);
        this.handleSelectedPanel = this.handleSelectedPanel.bind(this);
    }

    handleSelectedPanel(e) {
        this.props.onSelectedPanel(e.target.id);
    }

    render() {
        const { id, name, date, duration, exerciselist } = this.props.workout;
        return (
            <ExpansionPanel style={styles.panel} id={id} onChange={this.handleSelectedPanel}>
                <ExpansionPanelSummary>
                    <Typography variant="button" style={{ width: "33%" }}>
                        {name}
                    </Typography>
                    <Typography variant="button" style={{ width: "33%" }}>
                        ({date})
                    </Typography>
                    <Typography align="right" style={{ width: "33%" }}>
                        ~{duration} mins
                    </Typography>
                </ExpansionPanelSummary>
                <ExpansionPanelDetails>
                    <Table size="medium" style={styles.table}>
                        <TableHead>
                            <TableRow>
                                <TableCell padding="none">Name</TableCell>
                                <TableCell padding="none" align="right"># of sets</TableCell>
                                <TableCell padding="none" align="right">reps</TableCell>
                                <TableCell padding="none" align="right">weight</TableCell>
                            </TableRow>
                        </TableHead>
                        <TableBody>
                            {exerciselist.map((exercise) => (
                                <ExerciseList
                                    key={exercise.id}
                                    exercise={exercise}
                                />
                            ))}
                        </TableBody>
                    </Table>
                    <ExpansionPanelActions disableSpacing style={styles.actionButton}>
                        <Button color="primary" size="small" disableRipple>
                            edit
                        </Button>
                    </ExpansionPanelActions>
                </ExpansionPanelDetails>
            </ExpansionPanel>
        )
    }
}

它似乎根本没有接受 id,当我尝试禁用该按钮时,它会抛出此错误:

警告:失败的 Prop 类型:无效 Prop disabled类型 function供应给ForwardRef(Button) ,预计boolean .

最佳答案

您看到的警告来自:

<Button
    variant="contained"
    color="primary"
    size="small"
    style={styles.button}
    disabled={this.handleButton}
>

在错误中,它说一个函数被传递给disabled,它应该是一个 bool 值,因此更改disabled所采用的 bool 值(而不是函数this.handleButton)。

e.target.id 里面没有你真正想要的东西(它实际上可能不是一个东西)。您可以使用 e.target.value 从类似输入的内容中获取值,您希望从正在使用的 DOM 节点获取某些信息,但在这种情况下,该信息并不是什么东西输入的内容实际上是组件已经在其范围内(在 props 中)的东西。所以代替:

handleSelectedPanel(e) {
    this.props.onSelectedPanel(e.target.id);
}

这样做

handleSelectedPanel(e) {
    this.props.onSelectedPanel(this.props.workout.id);
}

关于javascript - 如何识别数组的某个对象id来改变同一对象中元素的状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57453332/

相关文章:

javascript - 如何在数据表中的复杂标题上显示/隐藏列

reactjs - 在 Gatsby 上,如何使用 prop 进行 GraphQL 查询?

javascript - 被卡住加载 react 故事书

javascript - 如何在 React 渲染函数中异步等待?

reactjs - 在一行中渲染网格项目 - ReactJS 和 Material-UI

javascript - 猫头鹰旋转木马 |如何使用 CSS 更改 .Item 的大小

javascript - 如何保持父范围属性和隔离范围属性同步?

css - MUI - 如何在特定样式的组件中使用伪类

javascript - 如何使用 v-on :change to my vue method? 传递输入文本

Material-UI 草图文件