在前面的文章中,我们学习了 Solid 的响应式原理,深入了了解其实现方式。
这篇文章将主要深入解析组件内部props的原理,为什么结构后会导致响应式丢失?
我们以一个例子作为参考,由浅入深的讲解其中的奥秘。
Parent.tsx
import { createSignal } from 'solid-js'
import Child from './child'
export default function Props() {
const [name, setName] = createSignal('JinSo')
const [age, setAge] = createSignal(23)
const update = () => {
setName('Jason')
setAge(99)
}
return (
<section class='text-gray-700 p-8'>
<Child name={name()} age={age()} />
<button type='button' onClick={update}>
Update
</button>
</section>
)
}
Child.tsx
interface ChildProps {
name: string
age: number
}
export default function Child(props: ChildProps) {
return (
<div>
<div>name: {props.name}</div>
<div>age: {props.age}</div>
</div>
)
}
先来看看组件编译后是什么样子的,官网也提供了 Playground,可以进行尝试:
Parent.tsx
组件编译效果
import { template as _$template } from "solid-js/web";
import { delegateEvents as _$delegateEvents } from "solid-js/web";
import { insert as _$insert } from "solid-js/web";
import { createComponent as _$createComponent } from "solid-js/web";
var _tmpl$ = /*#__PURE__*/_$template(`<section class="text-gray-700 p-8"><button type=button>Update`);
import { render } from "solid-js/web";
import { createSignal } from "solid-js";
export default function Props() {
const [name, setName] = createSignal('JinSo');
const [age, setAge] = createSignal(23);
const update = () => {
setName('Jason');
setAge(99);
};
return (() => {
var _el$ = _tmpl$(),
_el$2 = _el$.firstChild;
_$insert(_el$, _$createComponent(Child, {
get name() {
return name();
},
get age() {
return age();
}
}), _el$2);
_el$2.$$click = update;
return _el$;
})();
}
render(() => _$createComponent(Props, {}), document.getElementById("app"));
_$delegateEvents(["click"]);
Child.tsx
组件编译效果
import { template as _$template } from "solid-js/web";
import { createComponent as _$createComponent } from "solid-js/web";
import { insert as _$insert } from "solid-js/web";
var _tmpl$ = /*#__PURE__*/_$template(`<div><div>name: </div><div>age: `);
import { render } from "solid-js/web";
function Child(props) {
return (() => {
var _el$ = _tmpl$(),
_el$2 = _el$.firstChild,
_el$3 = _el$2.firstChild,
_el$4 = _el$2.nextSibling,
_el$5 = _el$4.firstChild;
_$insert(_el$2, () => props.name, null);
_$insert(_el$4, () => props.age, null);
return _el$;
})();
}