在一个列表中,当 selected item change 了,如何合适的捕捉到这个改变?

2021-07-01 11:43:21 +08:00
 yazoox

如图,比如,当前选中的是 "Category3 -> Layout1",因为选中了,所以有高亮背景显示,等等。

如果此时,我选择了另外一个 Item, 比如“Category2 -> Layout2”,则,如何通知 Category3 -> Layout1 取消“选中”状态,然后 Category2 -> Layout2 则变为选中状态?

本来我的想法是,在这个组件 /app 的全局,添加一个 selectedItem 和一个 previousSelectedItem 变量,专门用于维护”选中“状态,每次 有鼠标点击一个 Item 的时候,发送消息,改变 selected & previous selected item,再进行渲染。

这样的话,我可能需要有一个 map, key 是 item's id, value 就是这个 item 对象。当 selected 对象改变时,通过这个 map,和 key 找到对应的 item,然后 改变它的 state,这样,react 就会只 re-render 这两个对象了,而不是 render 所有的 items.

但感觉不是很”优雅“,所以,来请教一下大家。有没有更好的方法。

谢谢!

p.s.
框架使用的是 react, redux or useReducer.

1549 次点击
所在节点    React
8 条回复
alfredhot
2021-07-01 12:37:26 +08:00
所有 Category 下的每个 Layout 都赋不同的值,
然后将 Click(或者 selecteItem)函数提升到上一级.
用一个 selectedItem state 来控制状态就可以.
不知到你说的是不是这个效果.

下面的代码撸得匆忙, 瑕疵较多, 希望不要介意.

https://gist.github.com/alfredhot/03bdcf17ec52e847211ed3bb11fa4b40


还有就是, 为什么是 Cagetory ...
Leviathann
2021-07-01 13:28:58 +08:00
一般是把被选中的 item 由 item list 的上层组件维护
lybcyd
2021-07-01 13:32:00 +08:00
如果没有特殊需求,不需要保存前一个被点击的条目吧。只需要在树状组件维护一个叫 selected 的 state,用于保存被选中 layout 的 ID 。在循环渲染中,如果该 layout 被选中,传一个 active 为 true 的 prop,用于标记高亮就可以了。当进行点击时,触发一个 change 事件,把点击的 layout ID 作为参数传递,在树状组件处修改 selected 即可。
yazoox
2021-07-01 13:47:25 +08:00
@alfredhot

Category 仅仅只是一个名字,测试用例,别在意。其实,都是 TreeNode
另,兄弟,你这个方法,每次有 selected item 变化,会全部重新渲染吧。这恰恰 就是我想避免的。因为列表可能会很大......
alfredhot
2021-07-01 13:58:24 +08:00
@yazoox

原来如此, 我就说应该不是这么单纯的问题!
我有空也得自己研究研究.
sleepwalker
2021-07-01 23:58:40 +08:00
可以考虑利用单选框,然后用:checked 选择器来施加选中样式
siweipancc
2021-07-02 09:09:36 +08:00
state 对象过大需要 react-reducer,也能做到父子依赖解藕,主要是 ui 渲染别崩了
yazoox
2021-07-02 14:46:30 +08:00
@siweipancc 兄弟,能详细说说么?或者有没有相关文档分享一下。谢谢
我现在也使用了 useReducer, 和 context,在 tree 的根组件处,useReducer,然后把 selectedItem 作为 props 传给子组件。
只要任何子组件的 onClick 触发了,就会 dispatch curent item,这样根组件就拿到当前 selectedItem,然后触发 re-render,再把 selectdItem 作为 props 传下去。

可是,这样的话,依然有上面的问题。因为组件的 props 内容变化了( props.selecteItem 变了),所以,子组件都会触发 re-render 。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/786877

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX