这节我们来修复一个问题:

点击切换户型后没反应,刷新之后才会生效。
这很明显,是我们加上的这段代码导致的:

只有 walls 为空数组的时候才会销毁绘制的房子。
但切换户型的时候,我们是直接换了另一个户型数据:

根本没有清空。
所以要加一下清空逻辑:


onConfirm={() => {
setData({
walls: [],
floors: [],
ceilings: [],
furnitures: []
});
setTimeout(() => {
setData(data1);
}, 0);
}}
onConfirm={() => {
setData({
walls: [],
floors: [],
ceilings: [],
furnitures: []
});
setTimeout(() => {
setData(data2);
}, 0 );
}}
改成点击切换户型的时候,先清空,然后一秒之后设置新的数据。
当墙的数组为空的时候,也不渲染:


if(!data.walls.length) {
return;
}
2D、3D 的都要改下。
试下效果:

户型可以切换了,但现在墙可见性的计算不对了:

这是为什么呢?

因为这个函数引用的 data 是第一次的,形成了闭包,所以后面切换了户型用的也是之前的 data。
解决方式就是让 data 变成动态获取的。

const dataRef = useRef<State['data']>(null);
dataRef.current = data;
dataRef.current!.walls.forEach((item, index) => {
我们加了一个 ref 来保存每次渲染的 data。
计算墙可见性的时候动态从 ref 里取最新的 data。
这样切换户型之后墙的可见性的计算依然是对的:

这样切换户型的问题就解决了。
然后我们来改下右边这部分的样式:

它会挡住小视图。
在酷家乐里是这样做的:

会把小视图的空间留出来。
我们也这样改下:

.Properties {
height: calc(100vh - 60px - 200px);
top: auto;
width: 240px;
bottom: 0;
}
高度在之前的基础上减去小视图的高度。
设置绝对定位在底部。
宽度改为小视图宽度。
这里也要改下:


这样,右边的面板就不会挡住小视图了。
案例代码上传了小册仓库
总结
这节我们修复了两个问题。
一个是户型切换不生效,我们首先把数据清空,然后再设置新数据就好了。还有墙可见性计算的函数里用的 data 要换成动态获取的,我们用 ref 的方式来获取。
另一个是右边面板会挡住小视图,我们调整了下位置和高度。
bug 修完了,下节我们继续来做家具列表的功能。