Ссылки на элементы: ref
Ссылка (ref) — это доступ к настоящему DOM-элементу, который создал JSX. Она нужна, когда с элементом надо сделать то, чего не выразить атрибутами: поставить фокус в поле, прокрутить список, измерить размер, подключить стороннюю библиотеку.
Ссылка в переменную
В Solid JSX создаёт настоящие DOM-узлы, поэтому ссылка — это обычная переменная, в которую Solid записывает элемент:
// src/components/NewTodo.jsx
import { onMount } from 'solid-js';
export default function NewTodo() {
let input;
onMount(() => {
input.focus();
});
return <input ref={input} placeholder="Новая задача" />;
}Выведите <NewTodo /> в src/App.jsx. После загрузки страницы курсор сразу стоит в поле ввода. Переменная объявлена через let, потому что Solid присваивает ей значение при создании элемента.
Когда элемент доступен
| Место | Значение input |
|---|---|
Тело компонента, до return | undefined, элемент ещё не создан |
onMount | Элемент, уже вставленный в страницу |
| Обработчик события | Элемент |
Поэтому работу со ссылкой размещают в onMount, эффектах и обработчиках.
Ссылка в обработчике
После добавления задачи удобно очищать поле и возвращать в него фокус:
// src/components/NewTodo.jsx
export default function NewTodo(props) {
let input;
const add = () => {
props.onAdd(input.value);
input.value = '';
input.focus();
};
return (
<div>
<input ref={input} placeholder="Новая задача" />
<button onClick={add}>Добавить</button>
</div>
);
}Использование: <NewTodo onAdd={(title) => console.log(title)} />. После нажатия текст попадает в консоль, поле очищается, курсор возвращается в него.
Ссылка-функция
В ref можно передать функцию. Solid вызовет её с элементом сразу после создания:
// src/components/TodoList.jsx
export default function TodoList() {
return (
<ul ref={(el) => console.log('Список создан', el)}>
<li>Купить молоко</li>
</ul>
);
}В консоли появится сообщение с элементом ul. Такая форма нужна, например, чтобы передать элемент родителю через пропс.
Частая ошибка
Объявить ссылку через const или обращаться к ней в теле компонента:
// src/components/NewTodo.jsx
export default function NewTodo() {
let input;
// Неправильно: элемента ещё нет
// input.focus();
return <input ref={input} />;
}В момент выполнения тела компонента элемент ещё не создан, и вызов input.focus() выдаст ошибку. С const Solid не сможет записать элемент в переменную. Используйте let и обращайтесь к ссылке в onMount или в обработчиках.