Как передается функция в дочерний компонент?
Компоненты
Функция передаётся дочернему компоненту как обычный проп — это стандартный способ сообщать данные снизу вверх.
Базовый пример
const Parent = () => {
const [query, setQuery] = useState('');
const handleChange = (value) => setQuery(value);
return <SearchInput onChange={handleChange} />;
};
const SearchInput = ({ onChange }) => (
<input onChange={(e) => onChange(e.target.value)} />
);Ребёнок не знает, что делает функция, — он лишь сообщает о событии. Состояние меняется у владельца (родителя), новые props спускаются вниз. Однонаправленный поток сохраняется.
Соглашения
- Именование:
onSomethingдля пропа-колбэка,handleSomethingдля обработчика в компоненте. - Передавать ссылку, а не вызов:
onClick={handleClick}(неhandleClick()). - Нужны дополнительные аргументы — стрелка или частичное применение:
onClick={() => onSelect(item.id)}.
Стабильность ссылки
Функция, объявленная в теле компонента, пересоздаётся каждый рендер. Если ребёнок обёрнут в React.memo или кладёт колбэк в зависимости своих хуков, это ломает оптимизацию:
const handleSelect = useCallback((id) => select(id), [select]);useCallback стабилизирует ссылку; без memo у ребёнка он обычно не нужен.
Ловушки
- Инлайн-стрелка (
onClick={() => ...}) удобна, но всегда новая — не сочетается с memo-детьми. - Устаревшие замыкания при неполных deps useCallback — колбэк видит старый state; лечится функциональными сеттерами.
- Сеттер useState (
setQuery) можно передавать напрямую: он стабилен.
Коротко для собеседования
Функция передаётся пропом (onChange={handleChange}) — ребёнок вызывает её, состояние меняется у родителя. Передавать ссылку, а не вызов; для memo-детей и зависимостей хуков стабилизировать через useCallback (сеттеры useState уже стабильны); следить за устаревшими замыканиями.