В nodejs окружении нету document, т. к. это часть браузерного API. Мы пишем тесты на jest, и там используется https://github.com/jsdom/jsdom. Не подскажу как насторить mocha, но можно попробовать подключить jsdom. Eсли не хочется тянуть либу то можно замокать, или может запускать тесты в браузере.
Аннотации работают, но нужно что-то настроить. В vscode это работает через typescript. Если не ошибаюсь нужен jsconfig.json. Несколько лет назад я так работал на проекте с JS + JSDoc, и всё это заводил. Как по мне, с typescript это не сравнить. Минимальный функционал IDE это даёт, но никаких надёжных рефакторингов и гарантий по факту нет.
Сомневаюсь что typescript станет web стандартом. Скорее уже WASM допилят и туда можно будет компилировать другие языки.
Это эксперементальное API, в официальной документации не описано. Соотносить селекторы на уровне того как в статье — для свойств объекта первого уровня — не проблема. Каждое свойство получает маску по типу 0b1 << номер_свойства. И тогда селектор это селектор_свойста_1 | ... | селектор_свойства_n. Как-то соотносить это автоматически наверное можно, но нужно использовать свой API. Например useContextSelector(context, ["foo", "bar"]). Или может какой-нибудь babel плагин, что-бы посчитать заранее.
Это может работать когда у нас есть несколько независимых свойств в контексте, но не для чего-то по типу redux.
В случае создания своей обертки над React.createContext, нет нужды лезть в кишки реакта и что-то делать с _currentValue. Можно сделать обёртку над провайдером, которая будет хранить не значение контекста, а что-то вроде observable:
function CustomProvider({ value, children }) {
// observableValue создается едоножды и соответственно не вызывает перерисовок
const [observableValue] = useState(() => new ObservableValue());
useEffect(() => {
// засовываем туда наше значение из контекста
// под капотом `setValue` должен посчитать что изменилось и оповестить соответствующих слушателей
observableValue.setValue(value);
}, [value]);
return (
<Context.Provider value={observableValue}>{children}</Context.Provider>
);
}
И в кастомной обертке над React.useContext:
function useMyCustomContext(context) {
const observableValue = useContext(context);
const [, update] = useState(0);
// вместо boolean лучше использовать число
const forceUpdate = useCallback(() => {
update(prev => prev + 1);
}, [update])
useEffect(() => {
// детали я оставил за кадром
// тут мы подписываемся только на интересующие нас поля по какому-то правилу `rule`
// это может быть списко полей объекта или функция, или что-то ещё.
// например если мы хотим использовать Proxy как в статье, то
// `observableValue.getValue()` может вернуть Proxy, который будет создавать `rule`
observableValue.listen(rule, () => forceUpdate()))
}, [])
return observableValue.getValue();
}
При это в имплементации может быть любая существующая библиотека для реактивности, например rxjs или mobx.
опора на внутреннюю реализацию реакта, которая в будущем может поменяться все проблемы Monkey patchинга нельзя использовать в классовых компонентах — только вместо useMyCustomContext нужна похожая обертка для классов нельзя использовать один контекст в нескольких провайдерах
Если использовать webpack-dev-middleware то (вроде бы) можно сделать это без перезапуска процесса, а просто заставить сработать watcher, что будет немного быстрее и всё in-memory состояние сохраниться. Но если всё уже работет, то смысла переделывать наверное уже нет.
У вебпака есть програмный API, и у webpack-dev-server тоже
соответственно можно поднять свой express и и приделать API для перезапуска. В теории должно быть можно так сделать, но знаю насколько просто.
Мы использовали такое когда в там ещё не было встроенного прокси.
Да, я согласен, это довольно слабый аргумент, по сравнению с остальными, но я так понимаю, это основано на отзывах. Хуки заменили сложности с this на замыкания и ссылочное равенство. Ещё часть про "Classes confuse both people and machines" относится к проблемам с минификаторами и typescipt'ом. Поля классов не могут быть минифицированы без проблем и вывод типов хромал, особенно с HOC.
Хуки были созданы для решения проблемы переиспользования логики привязанной к жизненному циклу компонента. До этого использовали HOC и Render props, а ещё раньше — миксины. Проблема HOC — общее пространство имен пропсов, а render props засоряют дерево компонентов и всё это не удобно композировать.
Хуки позволяют удобно управлять тем, куда передавать и откуда брать пропсы. Например можно с легкостью подключить один хук несколько раз с разными пропсами, можно передавать выход из одного хука в другой и т.д.
У хуков конечно есть и свои проблемы, но они решили определенный класс проблем.
Потому что браузерам не очень прикольно поддерживать множество различных режимов работы JS. В strict mode зашли изменения, в том числе мешающие оптимизациям и необходимые для ES6+.
Prettier переносит строки в зависимости от длинны. Иногда увеличение\уменьние длины строки на пару символов попадает на брейкпоинт и происходит переформатирование.
Для тестов: EQAYFlAqxFYuWluL9qWMJIEPxVsoaVXAxIWWgAzwDeWWrdE1
Invoice на 3.50: ton://transfer/EQAYFlAqxFYuWluL9qWMJIEPxVsoaVXAxIWWgAzwDeWWrdE1?amount=3500000000
Ну у миксинов были проблемы с конфликтами имен и неявными зависимостями между миксинами, поэтому от них отказались в пользу HOC'ов. Еще из плюсов для хуков это возможность подключить один хук несколько раз. Вообще говоря классы в React тоже имеют мало общего с ООП, а о наследовании компонентов вообще упоминать не принято.
Не буду спорить с тем, что принципиально возможно сделать нормальный API и для классов, но в текущей реализации хуки удобнее классов.
Одно из ключевых преимуществ хуков перед классами это возможность создавать переиспользуемые и комбинируемые куски логики. Хуки являются однозначно более удобным решением чем Render Props, и нередко более удобны, чем HOC'и. Именно возможность удобно создавать кастомные хуки является самой мощной фичей хуков. Если честно, я совсем не против API классов, но там была проблемы именно с выделением кусков логики и привязки к конкретному компоненту. Я не совсем представляю как можно решить именно эту проблему через API классов.
В nodejs окружении нету
document
, т. к. это часть браузерного API. Мы пишем тесты наjest
, и там используется https://github.com/jsdom/jsdom. Не подскажу как насторитьmocha
, но можно попробовать подключить jsdom. Eсли не хочется тянуть либу то можно замокать, или может запускать тесты в браузере.Аннотации работают, но нужно что-то настроить. В vscode это работает через typescript. Если не ошибаюсь нужен jsconfig.json. Несколько лет назад я так работал на проекте с JS + JSDoc, и всё это заводил. Как по мне, с typescript это не сравнить. Минимальный функционал IDE это даёт, но никаких надёжных рефакторингов и гарантий по факту нет.
Сомневаюсь что typescript станет web стандартом. Скорее уже WASM допилят и туда можно будет компилировать другие языки.
Это эксперементальное API, в официальной документации не описано. Соотносить селекторы на уровне того как в статье — для свойств объекта первого уровня — не проблема. Каждое свойство получает маску по типу
0b1 << номер_свойства
. И тогда селектор этоселектор_свойста_1 | ... | селектор_свойства_n
. Как-то соотносить это автоматически наверное можно, но нужно использовать свой API. НапримерuseContextSelector(context, ["foo", "bar"])
. Или может какой-нибудь babel плагин, что-бы посчитать заранее.Это может работать когда у нас есть несколько независимых свойств в контексте, но не для чего-то по типу redux.
Что говорят разработчики реакта по этому поводу:
Приёмы для оптимизации
Обсуждение
Я так думаю это потому-что можно сделать что-то похожее очень просто. Конечно делать так не стоит, но руки у людей чешутся.
В случае создания своей обертки над
React.createContext
, нет нужды лезть в кишки реакта и что-то делать с_currentValue
. Можно сделать обёртку над провайдером, которая будет хранить не значение контекста, а что-то вроде observable:И в кастомной обертке над
React.useContext
:При это в имплементации может быть любая существующая библиотека для реактивности, например rxjs или mobx.
А ещё я бы рекомендовал посмотреть на второй аргумент в
useContext
иcreateContext
:React Context: a Hidden Power
Ещё можно использовать деструктуризацию объекта по отношению к массиву:
Если использовать
webpack-dev-middleware
то (вроде бы) можно сделать это без перезапуска процесса, а просто заставить сработать watcher, что будет немного быстрее и всё in-memory состояние сохраниться. Но если всё уже работет, то смысла переделывать наверное уже нет.У вебпака есть програмный API, и у webpack-dev-server тоже
соответственно можно поднять свой express и и приделать API для перезапуска. В теории должно быть можно так сделать, но знаю насколько просто.
Мы использовали такое когда в там ещё не было встроенного прокси.
Да, я согласен, это довольно слабый аргумент, по сравнению с остальными, но я так понимаю, это основано на отзывах. Хуки заменили сложности с this на замыкания и ссылочное равенство. Ещё часть про "Classes confuse both people and machines" относится к проблемам с минификаторами и typescipt'ом. Поля классов не могут быть минифицированы без проблем и вывод типов хромал, особенно с HOC.
Хуки были созданы для решения проблемы переиспользования логики привязанной к жизненному циклу компонента. До этого использовали HOC и Render props, а ещё раньше — миксины. Проблема HOC — общее пространство имен пропсов, а render props засоряют дерево компонентов и всё это не удобно композировать.
Хуки позволяют удобно управлять тем, куда передавать и откуда брать пропсы. Например можно с легкостью подключить один хук несколько раз с разными пропсами, можно передавать выход из одного хука в другой и т.д.
У хуков конечно есть и свои проблемы, но они решили определенный класс проблем.
Официальная мотивация
Потому что браузерам не очень прикольно поддерживать множество различных режимов работы JS. В strict mode зашли изменения, в том числе мешающие оптимизациям и необходимые для ES6+.
Есть уже готовая удобная обертка @testing-library/react-hooks
es6 модули разрешают пути относительно скрипта, из которого был сделан импорт
Если сервер на http://example.com, то запросы будут:
http://example.com/src/main.js
http://example.com/src/some/module.js
Несколько элементов в одном общем контейнере?
Prettier переносит строки в зависимости от длинны. Иногда увеличение\уменьние длины строки на пару символов попадает на брейкпоинт и происходит переформатирование.
Для тестов: EQAYFlAqxFYuWluL9qWMJIEPxVsoaVXAxIWWgAzwDeWWrdE1
Invoice на 3.50: ton://transfer/EQAYFlAqxFYuWluL9qWMJIEPxVsoaVXAxIWWgAzwDeWWrdE1?amount=3500000000
Тольуко у композиции функций немного другая сигнатура:
Ну у миксинов были проблемы с конфликтами имен и неявными зависимостями между миксинами, поэтому от них отказались в пользу HOC'ов. Еще из плюсов для хуков это возможность подключить один хук несколько раз. Вообще говоря классы в React тоже имеют мало общего с ООП, а о наследовании компонентов вообще упоминать не принято.
Не буду спорить с тем, что принципиально возможно сделать нормальный API и для классов, но в текущей реализации хуки удобнее классов.
Одно из ключевых преимуществ хуков перед классами это возможность создавать переиспользуемые и комбинируемые куски логики. Хуки являются однозначно более удобным решением чем Render Props, и нередко более удобны, чем HOC'и. Именно возможность удобно создавать кастомные хуки является самой мощной фичей хуков. Если честно, я совсем не против API классов, но там была проблемы именно с выделением кусков логики и привязки к конкретному компоненту. Я не совсем представляю как можно решить именно эту проблему через API классов.
Этот оператор не имеет никакого отношения к приведению к boolean. Этот оператор убирает null из типа.