You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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;

方案优势

  1. 符合官方设计:路径式更新是 createStore 的原生特性,所有更新都会触发精准的响应式重渲染,不存在状态不同步问题。
  2. 封装性强:子组件仅依赖自身 props,完全不知道顶层 store 的结构,复用性和可维护性更高。
  3. 无需嵌套 store:所有状态集中在顶层 store,避免了多层状态管理的复杂度,也不会出现嵌套 store 带来的潜在问题。
  4. 适配复杂嵌套:无论嵌套层级多深,只要传递对应路径的更新函数,就能安全、高效地更新嵌套属性。

内容的提问来源于stack exchange,提问作者Tim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 08:12:35