我想在Reaction中开发一个Tabs组件.当我试图关闭一个元素并将活动状态分配给上一个或下一个选项卡时,我的setFiles方法正确地更新了文件数组,但是当重新加载上下文时,派生状态openedFiles没有使用正确的文件状态.
这是我的代码:
context-provider.tsx个
const IdeEmulatorContextProvider: React.FC<{children: React.ReactNode}> = ({children}) => {
const [files, setFiles] = useState<IdeFile[]>([]);
const openedFiles = files.filter((element: IdeFile) => element.opened);
const selectFileHandler = (event: any) => {
// ...
};
const openFileInTab = (file: IdeFile) => {
// ...
};
const closeTab = (name: string) => {
setFiles((currentFiles: IdeFile[]) => {
let indexToUpdate: number;
const newFiles = currentFiles.map((element, index) => {
if (name === element.name) {
indexToUpdate = index;
return {
...element,
opened: false,
active: false
};
} else {
return element;
}
});
if (indexToUpdate! >= 1) {
newFiles[indexToUpdate!-1] = {
...newFiles[indexToUpdate!-1],
active: true
};
} else {
if (openedFiles.length > 1) {
newFiles[indexToUpdate!+1] = {
...newFiles[indexToUpdate!+1],
active: true
};
}
}
return [...newFiles];
});
};
const selectTab = (tabIndex: number) => {
setFiles((currentFiles: IdeFile[]) => {
const newFiles = currentFiles.map((element, index) => {
if (tabIndex === index) {
return {
...element,
active: true
};
} else {
return {
...element,
active: false
};
}
});
return [...newFiles];
});
};
const ctxValue = {
files,
openedFiles,
selectFileHandler,
openFileInTab,
closeTab,
selectTab
};
return <IdeEmulatorContext.Provider value={ctxValue}>
{children}
</IdeEmulatorContext.Provider>
};
tabs-list.tsx个
const TabsList = () => {
const ctx = useContext(IdeEmulatorContext);
const closeHandler = (name: string) => {
ctx.closeTab(name)
}
return <nav className="nav-bar">
<ol className="tabs">
{ctx.openedFiles.map((element: IdeFile, index: number) => <li key={element.name} className={element.active ? 'active' : ''} onClick={() => ctx.selectTab(index)}>
{element.name} {element.active ? <button className="btn-close" onClick={() => closeHandler(element.name)}>x</button> : null}
</li>)}
</ol>
</nav>
};
提前谢谢你了!