Пропсы
Пропсы — это данные, которые родительский компонент передаёт дочернему через атрибуты. Компонент получает их одним объектом props. В Solid этот объект реактивный: его поля читаются в момент обращения, поэтому важно, как именно вы их читаете.
Передача пропсов
Компонент читает текст задачи из props.title:
// src/components/TodoItem.jsx
export default function TodoItem(props) {
return <li>{props.title}</li>;
}Родитель передаёт значение атрибутом:
// src/App.jsx
import TodoItem from './components/TodoItem';
export default function App() {
return (
<ul>
<TodoItem title="Купить молоко" />
<TodoItem title="Позвонить Олегу" />
</ul>
);
}На странице два пункта с разным текстом.
Пропс из сигнала
Если передать в пропс сигнал, дочерний компонент будет обновляться вместе с ним:
// src/App.jsx
import { createSignal } from 'solid-js';
import TodoItem from './components/TodoItem';
export default function App() {
const [title, setTitle] = createSignal('Купить молоко');
return (
<div>
<ul>
<TodoItem title={title()} />
</ul>
<button onClick={() => setTitle('Купить хлеб')}>Изменить</button>
</div>
);
}После нажатия текст пункта меняется. Компилятор Solid превращает title={title()} в геттер, и props.title каждый раз читает свежее значение.
Почему нельзя деструктурировать
| Запись | Результат |
|---|---|
function TodoItem(props) и props.title в JSX | Обновляется |
function TodoItem({ title }) | Значение прочитано один раз и застыло |
const title = props.title в теле | Тоже застыло |
Деструктуризация читает поле сразу, в момент вызова компонента, а компонент вызывается один раз.
Значения по умолчанию: mergeProps
// src/components/TodoItem.jsx
import { mergeProps } from 'solid-js';
export default function TodoItem(props) {
const merged = mergeProps({ priority: 'обычный' }, props);
return <li>{merged.title} ({merged.priority})</li>;
}mergeProps объединяет объекты, сохраняя реактивность. Без атрибута priority выведется «обычный».
Разделение пропсов: splitProps
// src/components/Button.jsx
import { splitProps } from 'solid-js';
export default function Button(props) {
const [local, others] = splitProps(props, ['label']);
return <button class="btn" {...others}>{local.label}</button>;
}local получает label, а others — всё остальное, например onClick или disabled, и это передаётся кнопке целиком. Использование: <Button label="Добавить" onClick={add} />.
Дочерние элементы
Содержимое между открывающим и закрывающим тегом приходит в props.children:
// src/components/Card.jsx
export default function Card(props) {
return <section class="card">{props.children}</section>;
}<Card><p>Задач нет</p></Card> выведет абзац внутри section.
Частая ошибка
Писать компонент по привычке React — function TodoItem({ title }). На первый взгляд всё работает, но при изменении данных у родителя текст не обновится. Всегда принимайте props целиком и читайте props.title прямо в JSX.