如何实现类似CodeSandbox控制台的可拖拽拆分面板并修复状态冲突?
解决拖拽拆分面板的状态同步问题
问题分析
原代码通过toExpand状态条件渲染面板并设置preferredSize,但拖拽操作会直接修改面板尺寸却不更新状态,导致箭头图标和实际面板状态不一致。核心问题是状态和面板实际尺寸没有双向同步。
解决方案
不需要条件渲染面板,始终保留Console面板,通过监听面板尺寸变化同步状态,点击标题时切换面板的展开/收起尺寸:
修改后的代码
import React from "react"; import { Allotment } from "allotment"; import "allotment/dist/style.css"; import styles from "./App.module.css"; export default class App extends React.Component { constructor(props) { super(props); this.state = { consoleSize: 0, // 记录Console面板的尺寸 }; } // 切换面板展开/收起 toggleConsole = () => { this.setState(prev => ({ consoleSize: prev.consoleSize === 0 ? "50%" : 0 })); }; // 监听面板尺寸变化,同步状态 handleResize = (sizes) => { // sizes是数组,第二个元素是Console面板的尺寸 this.setState({ consoleSize: sizes[1] }); }; render() { const isExpanded = this.state.consoleSize > 0; return ( <div className={styles.container}> <Allotment vertical onResize={this.handleResize}> <Allotment.Pane>abc</Allotment.Pane> <Allotment.Pane preferredSize={this.state.consoleSize}> <div onClick={this.toggleConsole} style={{ cursor: "pointer" }}> Console {isExpanded ? "ArrowDown" : "ArrowUp"} </div> </Allotment.Pane> </Allotment> </div> ); } }
关键改进点
- 移除条件渲染:始终保留Console面板,避免拖拽时DOM重新渲染导致的冲突
- 双向同步状态:通过
onResize监听面板尺寸变化,实时更新consoleSize状态,确保箭头图标和实际面板状态一致 - 统一尺寸控制:点击标题时直接修改
consoleSize,Allotment会自动更新面板尺寸,拖拽操作也会同步更新状态
替代方案(使用react-split-pane)
如果allotment的使用体验不符合预期,可以尝试react-split-pane库,实现逻辑类似:
import React, { useState } from "react"; import SplitPane from "react-split-pane"; import "react-split-pane/lib/react-split-pane.css"; export default function App() { const [consoleSize, setConsoleSize] = useState(0); const isExpanded = consoleSize > 0; const toggleConsole = () => { setConsoleSize(prev => prev === 0 ? "50%" : 0); }; return ( <SplitPane split="vertical" defaultSize="100%" secondarySize={consoleSize} onChange={size => setConsoleSize(size)} > <div>abc</div> <div> <div onClick={toggleConsole} style={{ cursor: "pointer" }}> Console {isExpanded ? "ArrowDown" : "ArrowUp"} </div> </div> </SplitPane> ); }
内容的提问来源于stack exchange,提问作者SoftTimur
相关产品推荐
相关产品推荐

