Ответы пользователя по тегу React
  • Как правильно определить тип функции и события?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Мужик. Ты спик инглиш или как? MouseEventHandler переводится как "дрессировщик мышей для эвента" "обработчик событий мыши". KeyboardEventHandler как что? Правильно, "обработчик событий клавиатуры".
    Давайте подумаем, что же функция с такими типам может ожидать на вход, а? Может, соответственно, события мыши или клавиатуры(MouseEvent/KeyboardEvent)? Да не, бред какой-то.

    Но окей, дальше мы назначили пропсам интерфейс, где getCity таки имеет такой тип. И куда же мы передаём этот getCity? А передаём мы его в onSubmit. Скажи же мне, друже, submit - это событие клавиатуры? Или может быть это событие мыши? Ты уверен? Вот и мне кажется что нет.
    Ответ написан
  • Пишу первый раз на реакте, в чем проблема?

    Aetae
    @Aetae
    Тлен
    Вот это вот:
    root.render(
        <Header/>
    );

    Это магия под названием jsx. Она будет работать только если использовать специальные механизмы сборки, которые превратят сие непотребство в нормальный javascript.

    Если же ты хочешь просто вставить свой код на страницу без предвариательных танцев, то тебе придётся писать на чистом javascript, условно так:
    <script src="index.js" type="module"></script>
    import Header from './Header.js';
    
    const domContainer = document.querySelector('#container');
    const root = ReactDOM.createRoot(domContainer);
    root.render(
      React.createElement(Header)
    );

    function Header() { 
      return React.createElement('div', null, 'hsas')
    }
    export default Header;
    Ответ написан
    4 комментария
  • Почему не работает слушатель событий на элементах?

    Aetae
    @Aetae
    Тлен
    console.log.toString()
    Сайт подменяет консоль.

    Если используешь юзерскрипты, то можешь забрать консоль до того как её подменят:
    // @run-at document-start
    const myConsole = window.console;

    Если нет, но очень надо - можешь создать фрейм и забрать консоль оттуда.)
    Ответ написан
    Комментировать
  • Как грамотно настроить алиасы импортов?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Ну собсно по хардкору:
    1. Invalidate Caches если ещё не сделал.
    2. Закрыть, удалить папку .idea, открыть чтоб распарсил заново.
    3. Создать новый проект с заведомо рабочим конфигом и перекидывать туда кусками пока не сломается и так найти виновника.
    Ответ написан
  • Как исправить ошибку Element' is not assignable to type в React?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Ну очевидно, что NavLink не принимает функцию в качестве children. Могу предположить, что код у тебя для одной версии роутера, а используется другая.
    Ответ написан
    5 комментариев
  • Как вывести тип данных Data в заголовок?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    У тебя две совершенно разные проблемы в одном вопросе:

    1. TS тебе пишет ошибку, что тип Date не может быть children'ом для компонента, и это так. Однако дело в том, что тип у тебя задан неверно, на самом деле у тебя там никакой не Date а банальный string. Если ты поправишь типы, то всё заработает и выведет тебе то что ты передаёшь, т.е. 2012-03-23T08:25:44.962Z.

    2. Чтоб превратить строку 2012-03-23T08:25:44.962Z в строку Created 7 years ago надо либо руками написать соответствующую функцию, либо воспользоваться какой-либо библиотекой для работы с датами. Например с помощью moment это будет выглядеть примерно так:
    const createdFromNow = `Created ${
      moment.duration(moment().diff(data.createdAt)).humanize()
    } ago`;
    Ответ написан
    Комментировать
  • React-moment как изменить локализацию?

    Aetae
    @Aetae
    Тлен
    Идёшь на гитхаб, находишь где лежит эта фраза в локали. После чего просто патчишь локаль как надо:
    moment.updateLocale('uz-latn', {
      relativeTime: {
        past: '%s oldin'
      }
    });

    Или, если изменение нужно только в одном месте, то создаёшь отдельную:
    moment.defineLocale('uz-latn-short', {
      parentLocale: 'uz-latn',
      relativeTime: {
        past: '%s oldin'
      }
    });
    и используешь её где надо.
    Ответ написан
    Комментировать
  • Как правильно рендерить рекурсивный массив используя useMemo?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    useMemo - это не магическое заклинание. Оно работает сверяя изменения переданных props не более того.
    В твоём случае в useMemomemo надо обернуть сам компонент Replay, а не голый jsx.
    Ответ написан
    2 комментария
  • Как синхронизировать данные из localstorage между комонентами react?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Не используйте localStorage напрямую, напишите минимальюную обёртку-hook, положите в context или используйте одну из 100500 готовых библиотек для store в react.
    Ответ написан
    Комментировать
  • Как решить JSX element type 'LayoutMenu.Category' does not have any construct or call signatures?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    type Extensions = {
      Category: typeof LayoutMenuCategory;
      Item: typeof LayoutMenuItem;
    };

    Иначе оно для ts может быть также и undefined, а undefined - то, что написано в ошибке.
    Ответ написан
  • Как переделать этот код под TypeScript?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    TS тебе предельно понятно написал в чём проблема. Учись читать ошибки.

    Конкретнее же: у тебя не задан тип значения которое может принимать контекст, а выведено самим TS - null(потому что именно такое значение по умолчанию ты передал).
    export const Context = createContext<{
      sidebarIsOpen: boolean;
      toggleSidebar: (value: boolean) => void;
    } | null>(null)
    или лучше
    export const Context = createContext({
      sidebarIsOpen: false,
      toggleSidebar: () => {}
    });
    Ответ написан
    Комментировать
  • Как применить форму по нажатию enter?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Ну по enter у тебя же что-то происходит? Вот перед основным кодом триггерни blur руками:
    document.activeElement.dispatchEvent(new Event('blur'));


    Это конечно костыль, и по логике тебе надо написать кастомную обработку варианта с onChange, но и так, наверное, сойдёт.
    Ответ написан
    Комментировать
  • Почему я получаю undefined?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Ну в комменте уже ответили, что приходит тебе не совсем то, что ты там в типе написал.
    Рекомендую не писать руками интерфейсы для готового json, лучше тыкнуть в консоли на ответе "Copy object" и вставь в любой конвертер, который гуглится по "json to ts", например https://app.quicktype.io/. Так ты точно не ошибёшься, а потом уже можешь уточнить тип руками.

    В идеале, конечно, неплохо бы каждый ответ от сервера считать unknown и прогонять через тайпгард, проверяя руками, что он соответствует типу, но это не частая практика, увы.
    Ответ написан
  • Как вернуть стейт к начальному состоянию?

    Aetae
    @Aetae
    Тлен
    Никак. Использовать два стейта.
    Ответ написан
    Комментировать
  • Возможно ли реализовать более изящную типизацию объектов и деструктивное присваивание?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    А ты для начала придумай синтаксис для этого, который бы не вступал в прямой кофликт с JS и при этом был интуитивен.)
    Вот тут на тему много копий сломано, но, ИМХО, нет нормальных достойных релиза вариантов.)
    Ответ написан
    Комментировать
  • В чем причина ts ошибки при передаче пропсов в компонент?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Где-то среди >260 свойств из React.ComponentPropsWithRef<'select'> находится свойство, которое дженерик Option в Select устанавливает как string | number с большим приоритетом, чем то что ты кладёшь собственно в Options. Можешь поискать сам убирая по одному или сравнивая с декларацией для Select.

    Но в принципе решение просто выкинуть React.ComponentPropsWithRef<'select'>, т.к. ты расширяешь не нативный select, а react-select.
    import Select, { Props } from 'react-select';
    
    interface ISelectProps extends Props<OptionType> {
        caption?: string;
        disabled?: boolean
    }
    Ответ написан
  • Как указать в TypeScript интерфейсе, что в массиве могут содержаться много однотипных объектов?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    [ {title: string, cardList: []} ] - это не массив, заполняемый значениями типа {title: string, cardList: []}, это кортеж из одного значения данного типа.
    Массив обозначается так Array<{title: string, cardList: []}> или так {title: string, cardList: []}[].
    Кортеж используется когда нужно конкретное количество значений конкретного тип на конкретных позициях.
    Ответ написан
    1 комментарий
  • Стоит ли выносить код в отдельный компонент?

    Aetae
    @Aetae
    Тлен
    Всегда.
    Больше пяти строчек в разметке - отдельный компонент.
    Больше пяти строчек в коде - отдельный хук.)
    Ответ написан
    Комментировать
  • Как правильно затипизировать данный кусок кода?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Если не используете Node.js то просто исключите типы для неё из конфига TS.
    Тогда у вас setTimeout будет возвращать простой number, а clearTimeout будет принимать number | undefined. И никаких проблем.)

    Если же код ноды по каким-то причинам у вас идёт вперемешку со фронтовым кодом, то для фронтовых таймеров можете писать явно window.setTimeout и window.clearTimeout.
    Ответ написан
    Комментировать
  • Где размещать тесно связанные типы typescript?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Не слушай Василий Банников, плодить копипаст-типы точно не надо.

    А по размещению типов точно такая же логика как с обычными модулями. Так что абсолютно нормально импортировать связанные типы из связанного модуля. Все теории и паттерны проектирования применяются и тут.

    По хорошему конечно стоит придерживаться SOLID или чего-то подобного.
    Т.е. в Grid сделать тип IGridItemProps с теми свойствами которые точно нужны для работы Grid, а в GridItem наследовать от него уже конкретную реализацию
    interface GridItemProps extends IGridItemProps { ... }
    . Однако это нужно только если теоретически могут появиться ещё GridItemSuper и GrigItemNice, если же такого быть не может и модули(компоненты) сами по себе тесно связны, то заморачиваться не стоит.
    Ответ написан