Reactivity with SolidJS
Table of Contents
IntroductionRyan begins the course with a brief history of SolidJS and how it promotes a return to fine-grained reactivity and performance without relying on a virtual DOM.
Reactivity OverviewRyan describes reactivity as the ability to declaratively express the relationship between values that change over time. It consists of an observable state which notifies any derived values. When these values change a side effect like a render is triggered.
Signals & Side EffectsRyan explains the relationship between signals and side effects. Signals are the state exposed to the application through getters and setters. When a signal is used inside a side effect, the effect will re-execute.
DerivationsRyan demonstrate how derivations, or memoized values are only re-calculated when dependent values are changed. They act as a cache for expensive operations.
Dynamic Tracking & Advanced ReactivityRyan demonstrates how side effects can dynamically track changes to signals. Conditional logic can be added, and as the condition uses reactive properties, the effect will only run when dependent signals are changed.
Build a Reactive System
Creating a Signal from ScratchRyan creates a reactive signal from scratch. A global context array is used to store a list of observers that are subscribed to the signal. When the signal is updated, each observer's execute function is called.
Dynamic Reactivity from ScratchRyan implements the dynamic reactivity that conditionally re-runs the effect. A list of dependencies are added to the effect and subscriptions are bound to observers. A cleanup method is added to remove dependencies and ensure an infinite dependency loop is not created.
Implementing createMemo & untrackRyan implements the the createMemo method which creates a signal and an effect for that signal. The untrack function's implementation is also demonstrated in this lesson.
Fine-Grained Reactivity DemoRyan demonstrates the flexibility of the reactive code in the application. Local state can easily be moved to a global state and shared across components.
List ReactivityRyan discussed reactivity with HTML list elements. Rather than re-rendering the entire list when data changes, SolidJS provides components for iterating through the data and paginating. These components then decide what elements require updating.
ShowRyan introduces SolidJS control components. While SolidJS supports ternary operators for conditionally rendering components, the Show component provides a more declarative approach. The "when" attribute contains the condition and fallback content is provided for when the condition is false.
Switch, Dynamic, & ErrorBoundaryRyan uses the Switch component to avoid nested Show components. The Switch component contains multiple matches for determining what should be rendered. The Dynamic component behaves like a slot. It is passed a component to render.
For, Index, & PortalRyan demonstrates the differences between For and Index. For provides a reactive loop with keyed items. The index or position of each item is a signal, but the value is not. An Index behaves the opposite way. The index or position of each item is static but the value is provided as a signal.
Managing Props & Lifecycle MethodsRyan explains that SolidJS provides helper methods to maintain reactivity while executing more complex operations on component props like merging or spreading. Lifecycle methods like onMount and onCleanup are also explained in this lesson.
Props & ChildrenRyan demonstrates how to set default props with mergeProps and how to use splitProps to create a group of props to pass through to child components. The children helper method is also demonstrated in this lesson.
LifecyclesRyan demonstrates use cases for the the onMount and onCleanup lifecycle methods. The onMount method is useful for executing API requests or screen measurements before the component renders. The onCleanup method could be used to remove listeners or clear intervals after an effect has run.
Spreads & DirectivesRyan demonstrates how to use the spread operator to populate a component's props object. Directives, which define reusable custom attributes, are also covered in this lesson.
Building an App
Setup SolidJS with ViteRyan uses Stackblitz to generate a new SolidJS project. The project is configured with Vite and an initial application is created.
Building a Todo AppRyan adds the initial form elements for displaying todo items. State properties are added for storing the list of todo items and an initial item is hard coded to test the markup.
Creating New TodosRyan adds an onKeyPress event to the input field for adding a new todo. The event will detect when the enter key is pressed. If the input is valid, the new todo item will be added to the todos signal.
Modifying TodosRyan adds the ability to toggle the completed state and remove a todo. A checkbox for toggling all the todo items is also added to the application.
View Filters & Clearing CompletedRyan implements the filters for the todo items. A footer is added to the application with toggles for all, active, and completed. A filter function is created to update the showMode signal. The final code can be found at the Stackblitz link below.
Stores & Context
StoresRyan demonstrates how nested stores provide fine-grained reactivity because nested updates are handled independently without the need for DOM diffing. SolidJS also provides an Immer-inspired produce method which allows mutations to occur with a writable proxy version of the store.
ContextRyan explains the Context API and demonstrates how to create a global state. Immutable stores that interface with libraries like Redux, Apollo, or XState can also be created.
Routing & Async
Client Side RouterRyan introduces the SolidJS client-side router and demonstrates how transitions are included in its implementation. A Suspense component wraps any UI component where content might be loaded. The Transition API provides pending and start helper methods for handling transitions between views.
Server FunctionsRyan demonstrates the server$ method which enables server-side fetching. Any code wrapped in this method will be executed on the server.