如何在Solid JS子组件中更新列表项?
Solid.js 可编辑嵌套对象列表的优雅实现方案
Solid.js 官方推荐的方案是利用 createStore 原生支持的路径式更新特性,为子组件生成绑定了当前数据项路径的专属更新函数。这种方式既保证了组件封装性,又无需嵌套 store,完全契合框架的响应式设计理念。
核心思路
顶层 store 集中管理所有人员数据,父组件为每个列表项生成一个仅负责更新该条数据的函数,传递给 <Person> 组件;<Person> 再为 <Address> 生成针对 address 属性的更新函数,逐层传递。子组件只需要调用这些专属函数更新自身数据,完全不需要依赖顶层 store。
代码实现
父组件(App.jsx)
import { createStore } from "solid-js/store"; import { For } from "solid-js"; import Person from "./Person"; function App() { // 顶层 store 存储人员列表 const [people, setPeople] = createStore([ { name: "Alice", age: 30, address: { city: "Beijing", street: "Main St 1" } }, { name: "Bob", age: 25, address: { city: "Shanghai", street: "Second Ave 2" } } ]); // 为每个人员生成专属更新函数,绑定其在列表中的索引路径 const createSetPerson = (index) => { return (updater) => setPeople(index, updater); }; return ( <div> <For each={people} children={(person, index) => ( <Person person={person} setPerson={createSetPerson(index())} /> )} /> </div> ); } export default App;
Person 组件
import Address from "./Address"; function Person(props) { // 直接使用父组件传递的 setPerson 更新自身基础信息 const updateName = (e) => { props.setPerson({ name: e.target.value }); }; const updateAge = (e) => { props.setPerson({ age: parseInt(e.target.value) || 0 }); }; // 为 Address 组件生成针对 address 属性的更新函数 const setAddress = (updater) => { props.setPerson({ address: updater }); }; return ( <div style={{ margin: "1rem 0", padding: "1rem", border: "1px solid #eee" }}> <input type="text" value={props.person.name} onChange={updateName} placeholder="Name" /> <input type="number" value={props.person.age} onChange={updateAge} placeholder="Age" style={{ margin: "0 1rem" }} /> <Address address={props.person.address} setAddress={setAddress} /> </div> ); } export default Person;
Address 组件
function Address(props) { // 更新 address 下的具体属性,支持对象式或函数式更新 const updateCity = (e) => { props.setAddress((prev) => ({ ...prev, city: e.target.value })); }; const updateStreet = (e) => { props.setAddress({ street: e.target.value }); }; return ( <div> <input type="text" value={props.address.city} onChange={updateCity} placeholder="City" /> <input type="text" value={props.address.street} onChange={updateStreet} placeholder="Street" style={{ margin: "0 0.5rem" }} /> </div> ); } export default Address;
方案优势
- 符合官方设计:路径式更新是
createStore的原生特性,所有更新都会触发精准的响应式重渲染,不存在状态不同步问题。 - 封装性强:子组件仅依赖自身 props,完全不知道顶层 store 的结构,复用性和可维护性更高。
- 无需嵌套 store:所有状态集中在顶层 store,避免了多层状态管理的复杂度,也不会出现嵌套 store 带来的潜在问题。
- 适配复杂嵌套:无论嵌套层级多深,只要传递对应路径的更新函数,就能安全、高效地更新嵌套属性。
内容的提问来源于stack exchange,提问作者Tim
相关产品推荐
相关产品推荐

