我对此感到非常困惑。我有一个选择框组件,其中有一个选定的 Prop 。如果为 true,我会在框中显示一个复选标记,如果为 false,则不会。现在我遇到的问题是,点击三次后它不再切换。
最奇怪的是,我确实向组件的“selected”属性传递了一个 true bool 值(请参阅日志),但是当我在该子组件中记录“selected”属性的日志时,它说它是 false。
有人知道为什么会有所不同吗?
下面看到的日志结果
父组件:Services.tsx
import React, { useReducer } from "react";
import { makeStyles } from "@material-ui/core";
import { ToggleBox } from "components/ToggleBox";
const useStyles = makeStyles((theme) => ({
container: {
display: "flex",
},
}));
const servicesReducer = (state, action) => {
switch (action.type) {
case "toggle option":
const isCurrentlySelected = state.selectedOptions.includes(
action.payload.name
);
let newSelectedOptions = state.selectedOptions;
if (isCurrentlySelected) {
newSelectedOptions = newSelectedOptions.filter(
(item) => item !== action.payload.name
);
} else {
newSelectedOptions.push(action.payload.name);
}
return {
...state,
selectedOptions: newSelectedOptions,
};
case "add options":
return {
...state,
};
}
};
export const Services = () => {
const classes = useStyles();
const [state, dispatch] = useReducer(servicesReducer, {
financialPlanning: {
description: "",
minHours: null,
maxHours: null,
minPrice: null,
maxPrice: null,
},
selectedOptions: [],
});
const check = state.selectedOptions.includes("financialPlanning");
console.log("check", check);
console.log("check2", state);
return (
<div className={classes.container}>
<ToggleBox
selected={check}
onClick={() => {
console.log("click");
dispatch({
type: "toggle option",
payload: { name: 'financialPlanning' },
});
}}
title="Financiële planning"
>
Hey
</ToggleBox>
</div>
);
};
子组件:ToggleBox.tsx
import React from 'react';
import { Box, Card, CardContent, Typography } from '@material-ui/core';
import { makeStyles } from '@material-ui/core/styles';
import RadioButtonUncheckedIcon from '@material-ui/icons/RadioButtonUnchecked';
import CheckCircleOutlineIcon from '@material-ui/icons/CheckCircleOutline';
import { responsivePadding } from 'helpers';
export interface ToggleBoxProps {
title: string;
description?: string;
rightIcon?: React.ReactElement;
selected: boolean;
focused?: boolean;
children?: React.ReactNode;
onClick?: () => void;
}
const useStyles = makeStyles(theme => ({
root: ({ selected, focused }: ToggleBoxProps) => {
let borderColor = theme.palette.grey[300];
if (focused) {
borderColor = theme.palette.primary.main;
} else if (selected) {
// eslint-disable-next-line prefer-destructuring
borderColor = theme.palette.grey[500];
}
return {
border: `1px solid ${borderColor}`,
height: '100%',
};
},
content: {
height: '90%',
display: 'flex',
flexDirection: 'column',
},
header: {
display: 'flex',
cursor: 'pointer',
flexDirection: 'row',
justifyContent: 'space-between',
paddingBottom: theme.spacing(2),
marginBottom: theme.spacing(2),
borderBottom: `1px solid ${theme.palette.divider}`,
color: theme.palette.text.secondary,
},
title: {
flex: 1,
marginLeft: theme.spacing(2),
},
}));
export const ToggleBox: React.FC<ToggleBoxProps> = (
props: ToggleBoxProps,
) => {
console.log('props toggleBox', props);
const { title, description, rightIcon, selected, children, onClick } = props;
console.log('selected check prop Togglebox', selected);
const classes = useStyles(props);
return (
<Card className={classes.root}>
<CardContent className={classes.content}>
<Box className={classes.header} onClick={onClick}>
{selected ? <CheckCircleOutlineIcon /> : <RadioButtonUncheckedIcon />}
<Typography className={classes.title} color='textSecondary'>
{title}
</Typography>
{rightIcon}
</Box>
<Typography variant='body2' color='textSecondary'>
{description}
</Typography>
{selected && children}
</CardContent>
</Card>
);
};
最佳答案
向 selectedOptions
数组添加值时,您的状态似乎发生了变化。 .push
就地改变现有数组。
case "toggle option":
const isCurrentlySelected = state.selectedOptions.includes(
action.payload.name
);
let newSelectedOptions = state.selectedOptions; // <-- saved reference to state
if (isCurrentlySelected) {
newSelectedOptions = newSelectedOptions.filter(
(item) => item !== action.payload.name
);
} else {
newSelectedOptions.push(action.payload.name); // <-- mutation!
}
return {
...state,
selectedOptions: newSelectedOptions,
};
无论添加还是删除,您都必须返回一个新的数组引用。您可以使用 Array.prototype.concat 向数组添加值并返回新的数组引用。
case "toggle option":
const isCurrentlySelected = state.selectedOptions.includes(
action.payload.name
);
let newSelectedOptions = state.selectedOptions;
if (isCurrentlySelected) {
newSelectedOptions = newSelectedOptions.filter(
(item) => item !== action.payload.name
);
} else {
newSelectedOptions.concat(action.payload.name); // <-- add to and return new array
}
return {
...state,
selectedOptions: newSelectedOptions,
};
关于javascript - react : Entering boolean 'true' as prop end up as 'false' in the component,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69521301/