我发明了一台tab手风琴。目前它工作得很好。它应:
为此,我使用了2个userEffect钩子和一个函数来处理单击事件。它也是从上下文中利用provider。我对我考虑表演的方法有点困惑。
如果我错了,请有人复习一下代码,并给出建议。
下面是我的代码和演示:
import React, {
createContext,
ReactNode,
useContext,
useEffect,
useState
} from "react";
import "./styles.css";
export interface ContextProps {
isExpand: number | null;
childHandler: (v: number) => void;
}
export const initialContextProps: ContextProps = {
isExpand: null,
childHandler(v: number) {}
};
export const parentContext = createContext<ContextProps>(initialContextProps);
const { Provider } = parentContext;
function Children({ label, si }: { label: string; si: number }): JSX.Element {
const { isExpand, childHandler } = useContext(parentContext);
const [classProps, setClassProps] = useState(false);
useEffect(
function () {
if (si === isExpand) {
setClassProps(true);
}
},
[setClassProps, si, isExpand]
);
useEffect(
function () {
if (si !== isExpand) {
setClassProps(false);
}
},
[setClassProps, si, isExpand]
);
function setClass(index: number) {
setClassProps((prev) => !prev);
childHandler(index);
}
return (
<li onClick={() => setClass(si)} className={classProps ? "expand" : ""}>
{label} :: {si} || {isExpand} -- {classProps}
{classProps && <div>Content</div>}
</li>
);
}
function Parent({ children }: { children: ReactNode }): JSX.Element {
const [isExpand, setIsExpand] = useState<number | null>(0);
function childHandler(si: number) {
setIsExpand(si);
}
return (
<Provider value={{ isExpand, childHandler }}>
<ul>{children} </ul>
</Provider>
);
}
export default function App() {
return (
<div className="App">
<Parent>
<Children key={1} label="Title-1" si={0} />
<Children key={2} label="Title-2" si={1} />
<Children key={3} label="Title-3" si={2} />
<Children key={4} label="Title-4" si={3} />
<Children key={5} label="Title-5" si={4} />
</Parent>
</div>
);
}发布于 2023-01-13 10:08:32
做的很好!然而,可以做一些改进:
si和index引用相同的东西,您应该在整个工作过程中保持命名的一致性。另一个例子是,Parent、Children、childHandler听起来令人困惑,请将它们重命名为您正在进行的实际操作,如Accordion、AccodionItem、onOpen等。关于代码的
基本上,你的代码对你想要的东西来说是过分的。
当提供者的值支柱发生变化时,所有提供者的后代消费者都会重新呈现。
expand状态可以由si === isExpand直接确定。useEffect回调具有完全相同的依赖关系,您可以将它们合并为一个,但同样,您不需要它们。考虑一下组件的数据结构。它可以是一个包含多个对象的数组,每个对象都具有属性id、label和isOpen。使其成为您的状态,并使用.map来呈现它们。通过这种方式,将传递到组件中的道具进行比较,如果道具保持不变,则跳过重新呈现,这样就更具有表现力。
https://codereview.stackexchange.com/questions/282530
复制相似问题