如图,比如,当前选中的是 "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.
我在codesandbox上面写了一个简化的版本。 大家有兴趣可以看看!
点击一个item后,会“选中”,显示方式是后面添加了5个*号。同时de-select上一次选中的item.
但这个方法”不好“,每次点击,都会全部re-render,一共13次。我一直希望只re-rend两次。 大家打开console看log,会有输出。
有没有高手,指点一二,谢谢!
1
alfredhot 2021-07-01 12:37:26 +08:00
所有 Category 下的每个 Layout 都赋不同的值,
然后将 Click(或者 selecteItem)函数提升到上一级. 用一个 selectedItem state 来控制状态就可以. 不知到你说的是不是这个效果. 下面的代码撸得匆忙, 瑕疵较多, 希望不要介意. https://gist.github.com/alfredhot/03bdcf17ec52e847211ed3bb11fa4b40 还有就是, 为什么是 Cagetory ... |
2
Leviathann 2021-07-01 13:28:58 +08:00 via iPhone
一般是把被选中的 item 由 item list 的上层组件维护
|
3
lybcyd 2021-07-01 13:32:00 +08:00 via Android
如果没有特殊需求,不需要保存前一个被点击的条目吧。只需要在树状组件维护一个叫 selected 的 state,用于保存被选中 layout 的 ID 。在循环渲染中,如果该 layout 被选中,传一个 active 为 true 的 prop,用于标记高亮就可以了。当进行点击时,触发一个 change 事件,把点击的 layout ID 作为参数传递,在树状组件处修改 selected 即可。
|
4
yazoox OP @alfredhot
Category 仅仅只是一个名字,测试用例,别在意。其实,都是 TreeNode 另,兄弟,你这个方法,每次有 selected item 变化,会全部重新渲染吧。这恰恰 就是我想避免的。因为列表可能会很大...... |
6
sleepwalker 2021-07-01 23:58:40 +08:00 via iPhone
可以考虑利用单选框,然后用:checked 选择器来施加选中样式
|
7
siweipancc 2021-07-02 09:09:36 +08:00 via iPhone
state 对象过大需要 react-reducer,也能做到父子依赖解藕,主要是 ui 渲染别崩了
|
8
yazoox OP @siweipancc 兄弟,能详细说说么?或者有没有相关文档分享一下。谢谢
我现在也使用了 useReducer, 和 context,在 tree 的根组件处,useReducer,然后把 selectedItem 作为 props 传给子组件。 只要任何子组件的 onClick 触发了,就会 dispatch curent item,这样根组件就拿到当前 selectedItem,然后触发 re-render,再把 selectdItem 作为 props 传下去。 可是,这样的话,依然有上面的问题。因为组件的 props 内容变化了( props.selecteItem 变了),所以,子组件都会触发 re-render 。 |