如何在React中结合数组使用Signals(@preact/signals-react)?
使用@preact/signals-react优化大数据对象的组件重渲染
我尝试用@preact/signals-react解决大数据对象引发的组件重渲染问题,场景为从网络请求获取会实时更新的对象。
直接属性的优化效果良好
对于对象的直接属性,Signals能有效减少重渲染次数:
export function Root(){ const mySignal = useSignal({ sub: { val: 1 }, arr: [{id: 1, name: "bob"}] }); return <div> <Counter signal={mySignal} /> <Array signal={mySignal} /> </div> } function Counter({ signal }) { const counter = useComputed(() => signal.value.counter); return ( <div> <p>{counter}</p> <button onClick={() => { signal.value = { ...signal.value, counter: signal.value.counter + 1 }; }} > Increment </button> </div> ); }
点击递增按钮时,仅Counter组件会重渲染,使用useSignals()装饰器时效果一致。
数组处理的性能痛点
但处理数组时情况完全不同:
function ArrayConsumer({ mySignal }: { mySignal: MySignal }) { const arr = useComputed(() => mySignal.value.someArr); return ( <> {arr.value.map((item) => ( // 渲染并编辑{item.name} <ArrayItem key={item.id} item={item} /> ))} </> ); }
由于直接使用arr.value,数组每次变化时整个列表都会触发重渲染。我原本期望官方能提供signalMap()这类专门处理列表的方法,但文档里只提到直接使用signal.value。
我考虑过把单个列表项包装成Signal,但不确定这是不是合理的实践。我原本以为Signals能提供和Mobx类似的性能与开发体验,但缺乏原生的列表支持会大幅降低它的实用性。
理想的实现方案
我期望能有这样的实现:
function ArrayItem(item) { // 假设item本身是一个Signal const name = useComputed(() => item.value.name); return ( <div contentEditable onChange={(e) => (item.value = { ...item.value, name: e.target.value })} > {name} </div> ); }
内容的提问来源于stack exchange,提问作者Uri Kutner
相关产品推荐
相关产品推荐

