Show/Hide 每个按钮的多个元素点击与 React JS 中的匹配索引
Show/Hide multiple elements of each button click with matching indexes in React JS
我有一个场景,其中有 2 个不同的组件(按钮和信息容器)。在每个按钮上单击我试图显示每个匹配的信息容器。我能够在我的按钮中实现所需的功能,但是当我将状态传回我的其他组件时,我只能显示匹配的索引。我想要的结果是,如果我单击导航中的一个按钮并且它有一个活动的 class,我的所有“信息容器”应该保持可见,直到“活动”class 为 toggled/removed。
JS:
...
const useStyles = makeStyles((theme) => ({
root: {
display: "flex",
"& > *": {
margin: theme.spacing(1)
}
},
orange: {
color: theme.palette.getContrastText(deepOrange[500]),
backgroundColor: deepOrange[500],
border: "4px solid black"
},
info: {
margin: "10px"
},
wrapper: {
display: "flex"
},
contentWrapper: {
display: "flex",
flexDirection: "column"
},
elWrapper: {
opacity: 0,
"&.active": {
opacity: 1
}
}
}));
const ToggleItem = ({ onChange, id, styles, discription }) => {
const [toggleThisButton, setToggleThisButton] = useState(false);
const handleClick = (index) => {
setToggleThisButton((prev) => !prev);
onChange(index);
};
return (
<>
<Avatar
className={toggleThisButton ? styles.orange : ""}
onClick={() => handleClick(id)}
>
{id}
</Avatar>
{JSON.stringify(toggleThisButton)}
{/* {toggleThisButton && <div className={styles.info}>{discription}</div> } */}
</>
);
};
const ToggleContainer = ({ discription, className }) => {
return <div className={className}> Content {discription}</div>;
};
export default function App() {
const data = ["first", "second", "third"];
const classes = useStyles();
const [value, setValue] = useState(false);
const handleChange = (newValue) => {
setValue(newValue);
console.log("newValue===", newValue);
};
return (
<>
<div className={classes.wrapper}>
{data.map((d, id) => {
return (
<div key={id}>
<ToggleItem
id={id}
styles={classes}
discription={d}
onChange={handleChange}
/>
</div>
);
})}
</div>
<div className={classes.contentWrapper}>
{data.map((d, id) => {
return (
<ToggleContainer
className={
value === id
? clsx(classes.elWrapper, "active")
: classes.elWrapper
}
key={id}
styles={classes}
discription="Hello"
/>
);
})}
</div>
</>
);
}
Codesanbox:
https://codesandbox.io/s/pedantic-dream-vnbgym?file=/src/App.js:0-2499
Codesandbox : https://codesandbox.io/s/72166087-zu4ev7?file=/src/App.js
您可以将选定的选项卡存储在一个状态中。这样你就不需要渲染 3(或更多)<ToggleContainer>
。在 <ToggleContainer>
中将选定的选项卡作为道具传递并在 <ToggleContainer>
中呈现选定的选项卡内容。
import React, { useState } from "react";
import "./styles.css";
import { makeStyles } from "@material-ui/core/styles";
import Avatar from "@material-ui/core/Avatar";
import { deepOrange } from "@material-ui/core/colors";
import clsx from "clsx";
const useStyles = makeStyles((theme) => ({
root: {
display: "flex",
"& > *": {
margin: theme.spacing(1)
}
},
orange: {
color: theme.palette.getContrastText(deepOrange[500]),
backgroundColor: deepOrange[500],
border: "4px solid black"
},
info: {
margin: "10px"
},
wrapper: {
display: "flex"
},
contentWrapper: {
display: "flex",
flexDirection: "column"
},
elWrapper: {
opacity: 0,
"&.active": {
opacity: 1
}
}
}));
const ToggleItem = ({ onChange, id, styles, discription }) => {
const [toggleThisButton, setToggleThisButton] = useState(false);
const handleClick = (index) => {
onChange(discription, !toggleThisButton);
setToggleThisButton((prev) => !prev);
};
return (
<>
<Avatar
className={toggleThisButton ? styles.orange : ""}
onClick={() => handleClick(id)}
>
{id}
</Avatar>
{JSON.stringify(toggleThisButton)}
{/* {toggleThisButton && <div className={styles.info}>{discription}</div> } */}
</>
);
};
const ToggleContainer = ({ className, selected }) => {
return (
<div className={className}>
{selected.map((item, idx) => (
<div key={idx}>Content {item}</div>
))}
</div>
);
};
export default function App() {
const data = ["first", "second", "third"];
const classes = useStyles();
const [selected, setSelected] = useState([]);
// action : False -> Remove, True -> Add
const handleChange = (val, action) => {
let newVal = [];
if (action) {
// If toggle on, add content in selected state
newVal = [...selected, val];
} else {
// If toggle off, then remove content from selected state
newVal = selected.filter((v) => v !== val);
}
console.log(newVal);
setSelected(newVal);
};
return (
<>
<div className={classes.wrapper}>
{data.map((d, id) => {
return (
<div key={id}>
<ToggleItem
id={id}
styles={classes}
discription={d}
onChange={handleChange}
/>
</div>
);
})}
</div>
<div className={classes.contentWrapper}>
<ToggleContainer styles={classes} selected={selected} />
</div>
</>
);
}
我有一个场景,其中有 2 个不同的组件(按钮和信息容器)。在每个按钮上单击我试图显示每个匹配的信息容器。我能够在我的按钮中实现所需的功能,但是当我将状态传回我的其他组件时,我只能显示匹配的索引。我想要的结果是,如果我单击导航中的一个按钮并且它有一个活动的 class,我的所有“信息容器”应该保持可见,直到“活动”class 为 toggled/removed。
JS:
...
const useStyles = makeStyles((theme) => ({
root: {
display: "flex",
"& > *": {
margin: theme.spacing(1)
}
},
orange: {
color: theme.palette.getContrastText(deepOrange[500]),
backgroundColor: deepOrange[500],
border: "4px solid black"
},
info: {
margin: "10px"
},
wrapper: {
display: "flex"
},
contentWrapper: {
display: "flex",
flexDirection: "column"
},
elWrapper: {
opacity: 0,
"&.active": {
opacity: 1
}
}
}));
const ToggleItem = ({ onChange, id, styles, discription }) => {
const [toggleThisButton, setToggleThisButton] = useState(false);
const handleClick = (index) => {
setToggleThisButton((prev) => !prev);
onChange(index);
};
return (
<>
<Avatar
className={toggleThisButton ? styles.orange : ""}
onClick={() => handleClick(id)}
>
{id}
</Avatar>
{JSON.stringify(toggleThisButton)}
{/* {toggleThisButton && <div className={styles.info}>{discription}</div> } */}
</>
);
};
const ToggleContainer = ({ discription, className }) => {
return <div className={className}> Content {discription}</div>;
};
export default function App() {
const data = ["first", "second", "third"];
const classes = useStyles();
const [value, setValue] = useState(false);
const handleChange = (newValue) => {
setValue(newValue);
console.log("newValue===", newValue);
};
return (
<>
<div className={classes.wrapper}>
{data.map((d, id) => {
return (
<div key={id}>
<ToggleItem
id={id}
styles={classes}
discription={d}
onChange={handleChange}
/>
</div>
);
})}
</div>
<div className={classes.contentWrapper}>
{data.map((d, id) => {
return (
<ToggleContainer
className={
value === id
? clsx(classes.elWrapper, "active")
: classes.elWrapper
}
key={id}
styles={classes}
discription="Hello"
/>
);
})}
</div>
</>
);
}
Codesanbox: https://codesandbox.io/s/pedantic-dream-vnbgym?file=/src/App.js:0-2499
Codesandbox : https://codesandbox.io/s/72166087-zu4ev7?file=/src/App.js
您可以将选定的选项卡存储在一个状态中。这样你就不需要渲染 3(或更多)<ToggleContainer>
。在 <ToggleContainer>
中将选定的选项卡作为道具传递并在 <ToggleContainer>
中呈现选定的选项卡内容。
import React, { useState } from "react";
import "./styles.css";
import { makeStyles } from "@material-ui/core/styles";
import Avatar from "@material-ui/core/Avatar";
import { deepOrange } from "@material-ui/core/colors";
import clsx from "clsx";
const useStyles = makeStyles((theme) => ({
root: {
display: "flex",
"& > *": {
margin: theme.spacing(1)
}
},
orange: {
color: theme.palette.getContrastText(deepOrange[500]),
backgroundColor: deepOrange[500],
border: "4px solid black"
},
info: {
margin: "10px"
},
wrapper: {
display: "flex"
},
contentWrapper: {
display: "flex",
flexDirection: "column"
},
elWrapper: {
opacity: 0,
"&.active": {
opacity: 1
}
}
}));
const ToggleItem = ({ onChange, id, styles, discription }) => {
const [toggleThisButton, setToggleThisButton] = useState(false);
const handleClick = (index) => {
onChange(discription, !toggleThisButton);
setToggleThisButton((prev) => !prev);
};
return (
<>
<Avatar
className={toggleThisButton ? styles.orange : ""}
onClick={() => handleClick(id)}
>
{id}
</Avatar>
{JSON.stringify(toggleThisButton)}
{/* {toggleThisButton && <div className={styles.info}>{discription}</div> } */}
</>
);
};
const ToggleContainer = ({ className, selected }) => {
return (
<div className={className}>
{selected.map((item, idx) => (
<div key={idx}>Content {item}</div>
))}
</div>
);
};
export default function App() {
const data = ["first", "second", "third"];
const classes = useStyles();
const [selected, setSelected] = useState([]);
// action : False -> Remove, True -> Add
const handleChange = (val, action) => {
let newVal = [];
if (action) {
// If toggle on, add content in selected state
newVal = [...selected, val];
} else {
// If toggle off, then remove content from selected state
newVal = selected.filter((v) => v !== val);
}
console.log(newVal);
setSelected(newVal);
};
return (
<>
<div className={classes.wrapper}>
{data.map((d, id) => {
return (
<div key={id}>
<ToggleItem
id={id}
styles={classes}
discription={d}
onChange={handleChange}
/>
</div>
);
})}
</div>
<div className={classes.contentWrapper}>
<ToggleContainer styles={classes} selected={selected} />
</div>
</>
);
}