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

SolidJS子节点尺寸变更无法触发父节点Effect问题求助

SolidJS思维导图应用:子节点尺寸变更时父节点createEffect未触发问题

我正在使用SolidJS开发一款思维导图应用,该应用以树形结构展示带内容的节点,并自动完成树形布局。布局需依赖div的渲染尺寸向上传递至父节点,但目前遇到子节点尺寸变更时,父节点的createEffect无法被触发的问题。

我已尽可能简化代码以复现问题,代码如下:

import { createEffect, type Component, For } from "solid-js";
import { createStore } from "solid-js/store";

let root = {
  id: 0,
  parentid: -1,
  text: "Root",
  ownHeight: 10,
  children: [],
  totalHeight: 10,
};
let initialState = { nodes: [root] };

const [state, setState] = createStore(initialState);
let a = {
  id: 1,
  parentid: 0,
  text: "initial child",
  ownHeight: 10,
  children: [],
  totalHeight: 10,
};

const Node = (props: any) => {
  let ref: any;

  createEffect(() => {
    if (props.parentid === -1) {
      console.log("Effect running for parent");
    } else {
      console.log("Effect running for child");
    }

    if (ref && props.text) {
      setState("nodes", (n) => n.id === props.id, "ownHeight", ref.offsetWidth);
    }

    if (props.children.length > 0) {
      let t = props.ownHeight;
      props.children.forEach((element: number) => {
        let n = state.nodes.find((i) => i.id === element);
        t += n!.totalHeight;
      });
      setState("nodes", (n) => n.id === props.id, "totalHeight", t);
    } else {
      setState(
        "nodes",
        (n) => n.id === props.id,
        "totalHeight",
        props.ownHeight
      );
    }
  });

  return <div ref={ref}>{props.text}</div>;
};

const changeownbox = () => {
  console.log("Changing content of child");
  setState(
    "nodes",
    (n) => n.id === 1,
    "text",
    "This is a text \n on two lines"
  );
};

const addChild = () => {
  setState("nodes", [...state.nodes, a]);
  setState("nodes", (n) => n.id === 0, "children", [a.id]);
};

const App: Component = () => {
  return (
    <div>
      <For each={state.nodes}>{(item) => <Node {...item} />}</For>
      <button onClick={addChild}>Add child</button>
      <button onClick={changeownbox}>Change child content</button>
    </div>
  );
};

export default App;

运行该应用后,控制台日志符合预期的有:

  • 父节点首次创建时输出“Effect running for parent”
  • 点击“Add child”创建子节点时输出“Effect running for child”
  • 子节点添加至父节点子列表时输出“Effect running for parent”
  • 点击“Change child content”时输出“Changing content of child”
  • 子节点内容修改时输出“Effect running for child”

但此时未出现预期的父节点“Effect running for parent”日志。

子节点创建时父节点的Effect会读取子节点的totalHeight属性(该属性属于store,具备响应式),我猜测可能是Effect首次运行时子节点尚未存在,导致依赖未建立?请问该如何解决?


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 20:03:34