As part of my annual routine, I'm exploring the "latest and greatest" JavaScript UI library. Solid.js's performance seemed compelling. 15 minutes into documentation and this is what I encountered. Can you guess which one of the ChildComponent* updates when the text input on the parent component is updated, and the props passed to the child?
export default function ParentComponent() {
const [value, setValue] = createSignal("");
return (
<div>
<ChildComponent value={value()} />
<input type="text" oninput={(e) => setValue(e.currentTarget.value)} />
</div>
);
}
const ChildComponent1 = ({ props }) => <div>{props}</div>;
const ChildComponent2 = (props) => {
const value = props.value || "default";
return <div>{value}</div>;
};
const ChildComponent3 = (props) => {
return <div>{props.value || "default"}</div>;
};
const ChildComponent4 = (props) => {
const value = () => props.value || "default";
return <div>{value()}</div>;
};
const ChildComponent5 = (props) => {
const value = createMemo(() => props.value || "default");
return <div>{value()}</div>;
};
const ChildComponent6 = (props) => {
props = mergeProps({ value: "default" }, props);
return <div>{props.value}</div>;
};
const ChildComponent7 = (props) => {
const { value: valueProp } = props;
const value = createMemo(() => valueProp || "default");
return <div>{value()}</div>;
};
const ChildComponent8 = (props) => {
const valueProp = props.value;
const value = createMemo(() => valueProp || "default");
return <div>{value()}</div>;
};
The answer is 3, 4, 5, 6. My takeaway is this: there are multiple ways of doing it right, but also a handful of gotchas. The only way to be safe is to keep the mental model of these partitions while you develop, test, debug, and code review. As a code reviewer, you can easily accept the wrong code. For now, I remain skeptical of Solid.js as solving the complexity woes of Reactive programming. I'm not sure React.js is better.