SolidJS:点击按钮重排信号数组后DOM未更新的问题
问题:点击按钮后SolidJS中For组件的DOM顺序未更新
我正在学习SolidJS的For流控制章节,点击按钮后控制台输出的数组顺序已经更新,但页面上的DOM元素顺序没有变化,代码如下:
import { render } from 'solid-js/web'; import { createSignal, For } from 'solid-js'; function App() { const [cats, setCats] = createSignal([ { id: 'J---aiyznGQ', name: 'Keyboard Cat' }, { id: 'z_AbfPXTKms', name: 'Maru' }, { id: 'OUtn3pvWmpg', name: 'Henri The Existential Cat' } ]); const rearrange = () => { const curCats = cats(); setCats([curCats[1],curCats[2],curCats[0]]); console.log(cats().map(cat => cat.name)); }; return ( <> <ul> <For each={cats()}>{(cat, i) => <li> <a target="_blank" href={`https://www.youtube.com/watch?v=${cat.id}`}> {i() + 1}: {cat.name} </a> </li> }</For> </ul> <button onClick={rearrange}>Rearrange</button> </> ); } render(() => <App />, document.getElementById('app'))
问题原因
SolidJS的For组件需要接收信号本身作为each的参数,而不是调用信号获取当前值(cats())。cats()只会在组件初始渲染时获取一次数组值,之后当你调用setCats更新信号时,For组件无法感知到这个变化,因此不会重新排列DOM元素。
修复方案
将For组件的each参数从cats()改为cats,让For订阅信号的变化:
<ul> <For each={cats}>{(cat, i) => <li> <a target="_blank" href={`https://www.youtube.com/watch?v=${cat.id}`}> {i() + 1}: {cat.name} </a> </li> }</For> </ul>
这样修改后,当你点击按钮调用setCats更新数组顺序时,For组件会感知到信号的变化,自动根据新的数组顺序重新渲染DOM元素,页面上的列表顺序就会同步更新了。
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

