Refs
Edit this pageRefs, or references, are a special attribute that can be attached to any element, and are used to reference a DOM element or a component instance. They are particularly useful when you need to access the DOM nodes directly or invoke methods on a component.
Accessing DOM elements
One way of accessing DOM elements is through element selectors such as document.querySelector
or document.getElementById
.
Since elements in Solid can be added or removed from the DOM based on state, you need to wait until the element is attached to the DOM before accessing it.
This can be done by using onMount
to wait until the element is attached to the DOM before accessing it:
Accessing DOM elements through element selectors is not recommended for this reason. As elements with the same selectors are added and removed from the DOM, the first element that matches the selector will be returned, which may not be the element you want.
JSX as a value
When wanting to directly access the DOM element, you can use JSX as a value and assign it to a variable.
This can be a convenient way to access the DOM element. It lets you access the element directly without having to wait until it is attached to the DOM, and it can be used multiple times without having to worry about duplicate selectors.
The downside to this approach is it separates the element and any child elements that are created from it from the rest of the DOM. This removes the ability to access the element directly from the variable, and reading through components that use JSX as a value can be more difficult to understand.
Refs in Solid
Solid provides a ref system that allows you to access the DOM element directly without having to wait until it is attached to the DOM. These assignments occur at creation time prior to the element being added to the DOM. This provides access directly to the elements for manipulation, such as animations and event handling.
To use ref
, you declare a variable and use it as the ref
attribute:
In TypeScript, you must use a definitive assignment assertion. Since Solid
takes care of assigning the variable when the component is rendered, this
signals to TypeScript that the variable will be assigned, even if it can't
confirm it. tsx let myElement!: HTMLDivElement;
Signals as refs
Signals can also be used as refs. This is useful when you want to access the element directly, but the element may not exist when the component is first rendered, or may be removed from the DOM at some point.
In this example, the paragraph element is only rendered when the show
signal is true
.
When the component initializes, the paragraph element does not exist, so the element
variable is not assigned.
Once the show
signal is set to true
, the paragraph element is rendered, and the element
variable is assigned to the paragraph element.
If you would like to see a detailed example of how refs are created and used, you can view an intera
visit this Solid playground example.
In this example, you can see when the element
variable is assigned, and when it is removed.
Forwarding refs
Forwarding refs is a technique that allows you to pass a ref from a parent component to a child component. This is useful when you want to access the DOM element of a child component from the parent component.
To forward a ref, you need to pass the ref to the child component, and then assign the ref to the child component's element.
When a child component receives a ref
attribute from its parent, the ref
is passed as a callback function.
This is regardless of whether the parent passed it as a simple assignment or a callback.
Once the child component receives the ref
, it can be assigned to the element that the child component wants to expose through the ref
attribute.
To access the ref
in the child component, it is passed as a prop:
In this example, the canvas
element is directly assigned the ref
attribute through the props.ref
variable.
This forwards the reference to the parent component, giving it direct access to the canvas
element.
Directives
Directives allow the attachment of reusable behaviours to DOM elements.
The use:
prefix is used to denote these custom directives.
Unlike props or attributes, directives operate at a lower level through providing fine-grained control over the elements they are attached to.
Directives are like callback refs but they enable two extra features:
- Having multiple directives on an element.
- Passing in reactive data to the callback.
A directive is essentially a function with a specific signature:
element
: The DOM element that the directive is applied to.accessor
: A function that gives access to the value(s) passed to the directive.
The directive functions are called at render time, but are called before the element is added to the DOM. Due to this order, elements are fully primed with their attributes, properties, or event listeners, therefore minimizing unexpected behaviors or premature interactions.
Within directives, you're able to perform a variety of tasks, including:
- creating signals
- initiating effects
- adding event listeners
- and more.
To learn more about directives and how they work with TypeScript, refer to our TypeScript for Solid guide.