Ответы пользователя по тегу React
  • Как протестировать функцию в компоненте React c jest /react testing library?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Если там хитрая логика, то лучше вынести в отдельную функцию и к ней наколбасить тестов через чистый jest. Эта функция должна получать все данные, с которыми работает, через параметр. Например, твой handleChangeRoadCosts сейчас берет некую data из замыкания, а надо это передавать доп. параметром. Тогда ты легко напишешь тесты.

    В самом компоненте остаётся обезжиренный вариант, не требующий тестов:
    import {myFunc} from '....';
    
    ........
    const handleChangeRoadCosts = (id: number, keyVal: string, val: string) => {
        return myFunc(id, keyVal, val, data);
    };
    Ответ написан
    4 комментария
  • Чем отличаются между собой контекст и глобальная переменная?

    Alexandroppolus
    @Alexandroppolus
    кодир
    0) Контексты могут быть вложенными. Компонент ищет ближайший провайдер. Это позволяет обернуть часть приложения в провайдер с другим значением, и такой кейс на глобальных переменных не сделать.

    1) упомянутый в комментариях ререндер компонента с хуком useContext на борту. Но это если само значение контекста меняется. Часто бывает, что значение постоянное (классический пример - подключение редукса к реакту), далее подразумеваю этот случай.

    2) DI для компонентов. Компоненты не резолвят сами свою зависимость, им её инжектят снаружи. Более гибко с т.з. архитектуры, тестируемости и т.д. Правда, с другой стороны, у компонента появляются неявные зависимости, но в контекст можно зашить значения по умолчанию.
    Ответ написан
    Комментировать
  • Как сделать промис на ожидание изменения переменной?

    Alexandroppolus
    @Alexandroppolus
    кодир
    если надо ждать наблюдаемую переменную, то вот: https://mobx.js.org/reactions.html#when
    Ответ написан
    3 комментария
  • В чём причина ошибки TS2769 и как её устранить?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Функции setFrame, isCreateBlankFalse и т.д. возвращают объект, у которого поле type имеет тип string

    задай им явно возвращаемое значение, по идее должно попустить
    export const setFrame = (titlle: string): setFrameActionType => ({ type: 'SETFRAME', payload: { titlle } });


    --
    ну и лучше называть типы с большой буквы, так исторически сложилось.
    Ответ написан
    Комментировать
  • Почему useReducer не принимает мой reducer?

    Alexandroppolus
    @Alexandroppolus
    кодир
    у тебя какая версия реакта? На моей 18-й всё норм.

    const [field, updateField] = useReducer(fieldReducer, []);
    работает без ошибок, применяется перегрузка

    function useReducer<R extends Reducer<any, any>>(
            reducer: R,
            initialState: ReducerState<R>,
            initializer?: undefined
    ): [ReducerState<R>, Dispatch<ReducerAction<R>>];
    Ответ написан
  • Почему не происходит перерисовка при изменении объекта?

    Alexandroppolus
    @Alexandroppolus
    кодир
    У тебя объект store - не наблюдаемый. Хочешь его сделать наблюдаемым, натрави на него mobx.

    А если на голом Реакте, то надо делать изменения через setItems, примерно так
    setItems((prev) => {
      const i = prev.findIndex(item => item.id === id);
      if (i < 0 || prev[i].isClicked) {
        return prev;
      }
      const newArr = [...prev];
      newArr[i] = {...prev[i], isClicked: true};
      return newArr;
    });
    Ответ написан
    Комментировать
  • Почему ошибка в передаче параметров в функцию в TypeScript?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Property 'children' does not exist on type 'AuthProviderProps

    Да, поменялось. FC теперь из коробки не содержит children

    type AuthProviderProps = PropsWithChildren<{
        userManager: UserManager;
    }>;
    Ответ написан
    Комментировать
  • Как react различает компоненты, находящиеся в одной позиции UI-дерева?

    Alexandroppolus
    @Alexandroppolus
    кодир
    пример 1:
    <>
          {
            rename ? (
              <div><Counter title='Щелкунчик' /></div>
            ) : (
              <div><Counter title='Counter' /></div>
            )
          }
          <button onClick={() => setRename(!rename)}>Переименовать</button>
        </>


    здесь у тебя первым чилдом в реактФрагменте всегда будут одни и те же фигурные скобки (да, это как бы отдельная нода в дереве реакта). В них всегда первый чилд - div (реакт определяет, что это один и тот же тип элемента), а в нем - Counter (снова определяемый как один и тот же). Потому для div и Counter не происходит перемонтирования, а только обновление пропсов.

    пример 2:
    <>
          { rename && <div><Counter title='Щелкунчик' /></div> }
          { !rename && <div><Counter title='Counter' /></div> }
          <button onClick={() => setRename(!rename)}>Переименовать</button>
        </>

    здесь у Фрагмента первый и второй чилды - фигурные скобки (т.е. это два разных независимых чилда). Ну и соответственно, в них то появляются, то исчезают свои чилды (элементы div с чилдом Counter), тут никаких связей между оными элементами из разных фигурных скобок не устанавливается.
    Ответ написан
  • Что не так с вызовом кастомного хука в React?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Нельзя просто так взять и вызвать хук в обработчике события. Да, здесь он как бы "внутри" Item, но это обман зрения )

    вот так попробуй:
    const useHint = (hintTime?: number): VoidFunction => {
      const dispatch = useAppDispatch();
    
      return () => {
        dispatch({ type: setHintState.type, payload: { state: true } })
        setTimeout(() => {
          dispatch({ type: setHintState.type, payload: { state: false } })
        }, hintTime && 300);
      };
    };
    
    ...
    
    const Item: FC = () => {
      const runHint = useHint(500);
    
      return (
        <>
            <CopyButton
              className='contacts-group-item-field__btn'
              onClick={() => {
                runHint(500);
                navigator.clipboard.writeText('test')
              }}
            />
        </>
      )
    }
    Ответ написан
    Комментировать
  • На каком этапе React очищает память от memo?

    Alexandroppolus
    @Alexandroppolus
    кодир
    При размонтировании компонента. Данные хранятся в дереве реакта, в узле, связанном с конкретным элементом, и при размонтировании просто отправляются в сборку мусора
    Ответ написан
    1 комментарий
  • Нормально если первый стейт менеджер для react который я буду учить - будет mobx, а не Redux?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Начинать можно. Если ты устроишься на проект с мобиксом, то всё норм. Но если понадобится потом изучать редукс или что-то в том же ФП-шном духе, то после мобикса тебя будут отягощать вопросы "нахрена они так всё усложняют???".

    когда переходишь наоборот (как было у меня), то вопросы чуть другого плана - "а что, так можно было???"
    Ответ написан
    Комментировать
  • Почему выходит ошибка Each child in a list should have a unique "key" prop?

    Alexandroppolus
    @Alexandroppolus
    кодир
    key надо выставлять не для Crumb, а для фрагмента:
    <React.Fragment key={...}>
        {idx >= 1 && <div> / </div>}
        <Crumb path={crumb.path} title={crumb.title} style={styles.crumbs} />
    </React.Fragment>


    ну и Math.random() для key - худшее, что ты мог придумать. Наверняка у crumb есть какой-нибудь id, вот его и надо использовать. Или, например, path, title, - что-то из них ведь уникальное, не повторяется в массиве crumbs?
    на крайний случай можно idx
    Ответ написан
    8 комментариев
  • Изучение React. Стоит ли читать книгу?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Глянул содержание. Книга не о паттернах или подходах, там просто описание реактовского и околореактовского API, ну может, какие-то беспрактисы, связанные с теми или иными хуками/тулзами/etc. Это всё есть в документации.
    Ответ написан
    4 комментария
  • Почему курсор переходит в начало строки в моем компоненте?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Зачем тебе эта содомия с contentEditable, если там по факту обычный текст без форматирования?? Сделай на православных инпутах, не морочь себе голову
    Ответ написан
    3 комментария
  • Почему типизация видит в переменной undefined?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Классический пример, когда не нужна связка useState+useEffect

    У тебя функция setFullNewsData вызывается только внутри useEffect. То есть "стейт" fullNewsData - никакой не стейт, а производное значение от квери-параметра seo. Соответственно его надо просто вычислять, скорее всего, с хуком useMemo. Впрочем, undefined при этом никуда не денется, но он совершенно по делу - неизвестно, что может быть в квери-параметре.

    так что предложение проверять fullNewsData остается актуальным.
    Ответ написан
    Комментировать
  • Как redux определяет, какие компоненты надо обновить?

    Alexandroppolus
    @Alexandroppolus
    кодир
    useSelector внутри себя использует хук useSyncExternalStore (точнее, хук, аналогичный ему)

    вкратце суть работы: из редуксового контекста (того самого, который использован внутри Provider) достается редуксовый же стор. Этот стор постоянный, но в нем есть состояние - объект, ссылка на который меняется при каждом изменении, ибо иммутабельность. Подписываемся на изменение этой ссылки (т.е. по факту на изменение любой части состояния), у стора есть метод subscribe для этого. При срабатывании эвента забираем наши данные селектором, и если результат селектора отличается от предыдущего раза, значит изменились именно наши данные и надо пнуть компонент, чтобы обновился, это уже useSyncExternalStore знает как сделать.
    Ответ написан
    Комментировать
  • Есть ли смысл использовать children в React?

    Alexandroppolus
    @Alexandroppolus
    кодир
    children - это совсем азы в Реакте. И если оно останется для тебя "чем-то непонятным", то да, дело дрянь.
    Ответ написан
    Комментировать
  • Как получить общий интерфейс из объединения React.FC?

    Alexandroppolus
    @Alexandroppolus
    кодир
    import { ComponentProps, FC } from 'react';
    
    type Foo = FC<42> | FC<'hello'> | FC<true>;
    type Result = ComponentProps<Foo>;
    Ответ написан
    Комментировать
  • Как с помощью useSelector извлечь данные которые ранее были получены с помощью RTK Query?

    Alexandroppolus
    @Alexandroppolus
    кодир
    довольно странный вопрос.
    с помощью useSelector ты можешь забрать любые данные из редуксового стора.
    насколько я знаю, RTK Query складывает результаты в стор, и кажется проблем быть не должно
    Ответ написан
  • Как отлаживать react приложения, чтобы можно было отслеживать значения переменных?

    Alexandroppolus
    @Alexandroppolus
    кодир
    Реактовские компоненты и хуки - это обычные функции, их можно дебажить той же самой хренью, которая на первой картинке.
    Ответ написан