API Changes to support better SSR
Breaking Changes:
Set State
Mutable form is no longer a default. It was strangely inconsistent as you could accidentally mutate in immutable forms. No indicator why it should behave differently and work. Increased the size of state
for everyone and added performance overhead with additional proxy wrapping. Also it was based on returning undefined meaning function forms could never return undefined to blank a vlue. Solid has changed it into a state setter modifier produce
after ImmerJS naming.
// top level
setState(produce(s => {
s.name = "John"
}));
// nested
setState('user', produce(s => {
s.name = "John"
}));
Prop APIs
After writing setDefaults
, cloneProps
, and about to introduce mergeProps
it became clear we can do this all with a single assignProps
helper. So the former has been removed and now we have:
// default props
props = assignProps({}, { name: "Smith" }, props);
// clone props
newProps = assignProps({}, props);
// merge props
assignProps(props, otherProps)
It follows the same pattern as ES Object.assign
adding properties to the first argument and returning it. Except this method copies property descriptors without accessing them to preserve reactivity.
freeze
& sample
have been renamed
These APIs never had the most obvious naming, borrowing from SRP and digital circuit concepts rather than common english. They are now batch
and untrack
respectively which better reflect their purpose. These are now deprecated and will be removed in next minor version.
Resource API
For better automatic hydration support it is prudent to change resource signatures to take functions that return promises rather than promises themselves. This factory function has a lot advantages. This allows the library to decide whether to execute it or not. In certain cases we can choose skipping creating the promise altogether. It also leaves the door open for things like retry.
We use this mechanism to wire up streamed data from the server and automatic data hydration for resources rendered into the page in async SSR.
SSR Improvements
New experimental support for Suspense aware synchronous, asynchronous, and streaming SSR with hydration, progressive hydration, and automatic isomorphic data serialization. Completely removed what was there before with a simple static generator and more examples, so all existing projects using solid-ssr
package will break with this release. This is a much better foundation, and I hope to build better things on top.
New
State Getters
For convenience of passing derived values or external reactive expressions through Solid's state initializer you can now add getter
's.
const [state, setState] = createState({
firstName: "Jon",
lastName: "Snow",
get greeting() { return `You know nothing ${state.firstName} ${state.lastName}` }
});
return <div>{state.greeting}</div>
Control Flow
Dynamic allows swapping Component dynamically.
// element tag name
const [comp, setComp] = createSignal("h1");
<Dynamic component={comp()} {...otherProps} />
// Component
setComp(MyComp);
ErrorBoundary catches uncaught downstream errors and shows a fallback.
<ErrorBoundary fallback={<div>Something went terribly wrong</div>}>
<MyComp />
</ErrorBoundary>
Portals render in the Head
You can now render portals in the head with no additional div element.
Multi-version detection
Common hard to track issue with Solid is when multiple versions of the library are running on the same page. It breaks reactivity, and is sometimes difficult to notice. Solid now detects if a version has already been loaded at runtime and complains.
Bug Fixes & Updates
Arguably a new feature but Solid now detects computation owners with pending dependency changes when trying to resolve nested computations. In so it will resolve those dependencies first. This fixes a long time issue with conditional processing with not directly related reactive atoms.
Improved TypeScript Types.