Некоторое время назад я был вынужден ковыряться в legacy, оставленным ушедшим разработчиком. Добавление фичи в код было хирургической операцией, которая легко могла сломать жизнеспособность страницы. Из-за нагроможденных useEffect с связями между собой, скорее всего, под конец, как работает код не понимал и сам автор. На проекте не было линтера
Мне очень помогли следующие хуки и сделанные по аналогии
1. useListEditor()
Хук, который можно использовать для обработки редактирования списка элементов. Позволяет сразу получить уже собранный массив в коллбеке
onChange, что упрощает применение изменений из списка
import { useListEditor } from "react-declarative"; export const EditableList = () => { const { onRemoveItem, onUpdateItem, onAddItem, render, } = useListEditor( (id, item) => ( <> <span>{`Label: ${item.label}`}</span> <span>{`Value: ${item.value}`}</span> <button onClick={() => onUpdateItem(id, { label: prompt("label", item.label), value: prompt("value", item.value) }) } > update </button> <button onClick={() => onRemoveItem(id)}>remove</button> </> ), { initialValue: [ { label: "foo", value: "bar" } ], onChange: (items) => console.log(items) } ); return ( <> <button style={{ marginBottom: 5 }} onClick={() => onAddItem({ label: "fiz", value: "baz" }) } > Add item </button> <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr auto auto", gridColumnGap: 5, gridRowGap: 5, maxWidth: 300 }} > {render()} </div> </> ); }; export default EditableList;
Посмотреть код хука useListEditor можно тут
2. useModalDialog()
Хук, который позволяет вывести модальное окно с привязкой к состоянию компонента. Дочернее древо элементов рисуется в
<ModelProvider>, который можно разместить вAppили другом нижестоящем компоненте
import { useState } from "react"; import { useModal } from "react-declarative"; export const ModalDialogExample = () => { const [value, setValue] = useState(1); const { showModal, hideModal } = useModal( () => ( <div> Sample modal with value {value} </div> ), [value] ); return ( <> <button onClick={showModal}>Show modal</button> <button onClick={hideModal}>Hide modal</button> <button onClick={() => setValue(value + 1)}>Increment</button> </> ); }; export default ModalDialogExample;
Посмотреть код хука useModalDialog можно тут
3. useActualCallback()
Позволяет достучаться до актуальной ссылки на коллбек из
useEffectдаже если функция не указана в зависимостях или не все состояния, используемые в функции, есть в зависимостях эффектаКазалось бы, при открытии формы должен появиться
alert()с содержимым{never: null}, однако, внутри коллбека значениеinitNotCompleteвсегда будет актуальным
import { useState, useEffect, useLayoutEffect } from "react"; import { useActualCallback } from "react-declarative"; export const ActualCallbackExample = () => { const [initNotComplete, setInitNotComplete] = useState(true); const [filterData, setFilterData] = useState({ never: null }); const handleChange = useActualCallback(() => { if (!initNotComplete) { alert(JSON.stringify(filterData, null, 2)); } }); useEffect(() => { handleChange(); }, [filterData]); useLayoutEffect(() => { setInitNotComplete(false); }, []); return ( <button onClick={() => setFilterData({ foo: "bar" }) } > Update filterData </button> ); }; export default ActualCallbackExample;
Посмотреть код хука useActualCallback можно тут
Спасибо за внимание!
Искренне надеюсь, что рассмотренные хуки помогут вам добавлять фичи в легаси ничего не сломав)
ссылка на оригинал статьи https://habr.com/ru/post/677248/
Добавить комментарий