Ответы пользователя по тегу React
  • Как импортировать useState в next.js?

    @slide13
    frontend/web-developer
    С 13й версии nextjs при использовании app роутинга компоненты по-умолчанию пытаются отрендериться на сервере, но для компонентов, которые требуют интерактивности на клиенте (например, компоненты с состоянием, кнопки, любые компоненты требующие браузерный api и т.д.) нужно добавлять директиву 'use client' в начале файла компонента, чтобы next понимал, что рендерить его надо на клиенте.

    Т.е. в вашем случае, компонент, который будет использовать useState, нужно выделить в отдельный файл и вверху файла добавить 'use client'.

    Ну и желательно почитать про это все тут вначале, либо использовать папку pages по старинке.
    Ответ написан
    Комментировать
  • Как обработать ошибку от createAsyncThunk в Redux toolkit?

    @slide13
    frontend/web-developer
    Вопрос: почему после запроса в блоке try
    await dispatch(fetchOrderCreate({...formData, type: 'pickup'}));
    Выполнение кода продолжается как ни в чем не бывало, и не попадает в блок catch.


    Потому что, если почитать документацию, то там будет написано, что createAsyncThunk всегда возвращает resolved промис, даже при ошибке. А чтобы возвращалась оригинальная ошибка нужно дополнительно вызвать unwrap:

    await dispatch(fetchOrderCreate({...formData, type: 'pickup'})).unwrap();
    Ответ написан
  • Как исправить баг соприкосновения двух Slice в RTK?

    @slide13
    frontend/web-developer
    Потому что кое что забыли в addMatcher. Сейчас у вас оба слайса в extraReducers матчатся на все асинхронно возвращаемые через промисы экшены, поэтому данные и записываются в оба слайса Т.е. вам необходимо матчить по название thunk + статус, а не только по статусу, как пример, для option:
    вот вы создали async thunk с типом "countries/fetchCountries"
    export const fetchCountries = createAsyncThunk(
      'countries/fetchCountries',
    ...

    и в addMatcher будет тогда:
    (action) => action.type.endsWith("countries/fetchCountries/pending"),

    Ну и везде так поменяйте.
    Ответ написан
    1 комментарий
  • Как добавить точку при клике в react-yandex-maps?

    @slide13
    frontend/web-developer
    У компонента Map добавить событие onClick, из которого можно получить текущие координаты, сохранить их и потом на основании полученных сохраненных координат отрендерить Placemark, который будет потомком Map

    const [coordinates, setCoordinates] = useState([])
    <YMaps ... >
      <Map ...
        onClick={e => setCoordinates(e.get("coords"))}
      >
      {coordinates.length && <Placemark
        geometry={coordinates}
        options={{
          zIndex: 100
        }}
      />}
      </Map>
    </YMaps>


    Что-то типа того, но возможно там что-то поменялось, потому что последний раз я эту библиотеку лет 5 назад использовал.
    Ответ написан
    1 комментарий
  • Какой тип у children с переданным ref?

    @slide13
    frontend/web-developer
    На сколько я понял в React.Children.map передается ref только из оригинального компонента, forward ref там отсутствует, именно поэтому тайпскрипт и ругается, что ref не существует.

    Видел только вариант добавить ref в клонированный элемент:

    {React.Children.map(props.children, (child, index) =>
      React.cloneElement(child, {
        ref: (ref) => (childrenRef.current[index] = ref)
      })
    )}

    что в доках реакта не рекомендуется, но по крайней мере это должно работать.
    Ответ написан
  • Как изменить стиль placeholder у input в функциональном компоненте React?

    @slide13
    frontend/web-developer
    Инлайн стили нельзя использовать для стилизации псевдо элементов. Если не хотите использовать внешний css, то можно взять css-in-js библиотеку например, styled-components или emotion
    Ответ написан
    Комментировать
  • Почему после загрузки страницы, не рендерится контент?

    @slide13
    frontend/web-developer
    Функция обновления состояния в реакт асинхронная. На момент выполнения FillGoods массив AllGoodsArray будет пустой, т.к. setAllGoodsArray еще не будет выполнена и состояние еще не обновлено.
    Здесь же AllGoodsArray вообще не нужен, можно в FillGoods просто передать response.data в качестве параметра.
    Еще не понятно, почему некоторые переменные и функции у вас названы в стиле PascalCase, лучше придерживаться консистентности всегда
    Ответ написан
    Комментировать
  • Чем заменить React.FunctionComponent?

    @slide13
    frontend/web-developer
    "Чем заменить React.FunctionComponent?" - ничем, так и использовать интерфейс FunctionComponent или тип FC.

    В конкретном коде проблема из-за отсутствия запятой в импорте, а не в типизации.

    Единственное, на будущее в 18й версии убрали children из FunctionComponent, поэтому при использовании children нужно его явно указывать в типизации пропов.
    Ответ написан
    5 комментариев
  • Почему компонент равен undefined?

    @slide13
    frontend/web-developer
    У вас в состоянии data объект, а в setData вы передаете 2 отдельных параметра из которых используется только первый как аргумент.
    поменяйте setData на:
    setData({state, panel})
    должно заработать
    Ответ написан
    Комментировать
  • Массив пустой, хотя я добавляю в него ID. Что не так?

    @slide13
    frontend/web-developer
    У вас в active ожидается, что id будет передаваться из компонента Universal, т.е. там должно быть onClick={() => active(id)}

    но id можно передать и сразу, тогда в Universal ничего править не надо, а внутри map сделать active={() => active(item.id)}
    Ответ написан
    Комментировать
  • Почему useRef работает неверно?

    @slide13
    frontend/web-developer
    Проблема не в useRef, проблема в том как работает console.log. Если в console.log передается объект, то он выводится по ссылке, в итоге получается, что когда обновляется ref, то браузер автоматом обновляет его в консоли.
    Чтобы проверить, что useRef работает как надо - достаточно вывести current значение из ref, т.е. console.log(t.current, 0)
    Если же нужно вывести именно объект на момент его логирования, то можно привести объект к строке и снова собрать в объект:
    console.log(JSON.parse(JSON.stringify(t, 0)))

    На MDN можно почитать про это
    Ответ написан
    2 комментария
  • Как поменять стили для одного элемента массива по клику?

    @slide13
    frontend/web-developer
    Например, так
    добавить css:
    #comp04 div .selected {
      background: #FF0000;
    }

    И заменить newColor:
    function newColor(e) {
      const element = e.target;
      if (element.classList.contains('selected')) {
        e.target.classList.remove('selected');
      } else {
        e.target.classList.add('selected');
      }
    }


    Ответ написан
    1 комментарий
  • Почему React npm start не работает после установки Styled components?

    @slide13
    frontend/web-developer
    Начиная с Node.js 17й версии там теперь используется OpenSSl 3.0, который, видимо, не поддерживается в одной из зависимостей стайлед компонентов.
    В качестве временного решения либо откатить ноду на 16ю версию, либо запускать с параметром --openssl-legacy-provider. Можно еще в старт скрипт прописать
    "start": "react-scripts --openssl-legacy-provider start"
    Ответ написан
    2 комментария
  • Как корректно передать элемент в рендер?

    @slide13
    frontend/web-developer
    Из того, что вижу я при беглом просмотре - у вас в качестве ключа в список ListItem передается undefined, т.к. у вас явно нет свойства key в текущем классе App (в консоли на это тоже ошибка должна быть). А так как ключи для всех элементов не заданы, то при добавлении в начало/середину списка нового элемента приводит к тому, что реакт неправильно высчитывает порядок элементов и из-за этого возникают такие странности при рендеринге списка.
    В качестве решения должно сработать поставить в качестве ключа тоже itemString, если он у вас дублироваться не будет, конечно, но все же лучше при создании таска присваивать ему уникальный id, т.е. в todoList будет не просто массив текстов, а массив объектов, где каждый объект будет содержать id и текст таска. Тогда можно будет и тексты одинаковые добавлять для разных задач и удалять проще будет.
    Также непонятно, для чего нужен key в стейте, если он не изменяется нигде.
    Ответ написан
    Комментировать
  • Как исправить 401 (Unauthorized)?

    @slide13
    frontend/web-developer
    Подозреваю, что ваш сервер не отдает 200 на preflight запрос OPTIONS, в итоге с браузера возвращается 401. В postman же все работает, т.к. это фича только браузера и postman не отправляет OPTIONS перед POST запросом.
    Если используется nodejs на сервере, то необходимо включить preflight запросы на нужные маршруты, либо для всех, например, можно сделать так:
    app.use(cors({ credentials: true, origin: true }))

    или разрешить для всех маршрутов через опции:
    app.options('*', cors())

    Почитать про preflight в express тут
    Ответ написан
  • Почему после dispatch не обновляется state на хуках?

    @slide13
    frontend/web-developer
    Опечатка - у вас передается payOlad, а данные в редюсере берутся из action.payload. Рекомендую поставить плагины, типа code spell checker, очень помогает.
    Ответ написан
    4 комментария
  • Как настроить разделение ролей (user, moder, admin) внутри проекта на React?

    @slide13
    frontend/web-developer
    Для начала, обязательно проверка ролей должна быть реализована на бэке, чтобы юзер не смог минуя ui выполнять не предназначенные для него действия или получать закрытые для него данные.

    Далее, самый простой вариант - это ограничение на уровне роутинга, тут все понятно в целом, когда перед переходом на отдельную страницу проверяется наличие прав, иначе показываем заглушку, что в этот раздел доступ ограничен.

    Если же требуется разделить на уровне ui одной страницы, когда у нас есть кнопка редактирования данных, например, но обычный юзер может только смотреть, а кнопка должна быть активна редактору/админу, то это уже придется делать на уровне компонентов и отдельной проверки определенных правил для конкретной роли.

    Например, я решал такую задачу следующим способом:
    1. Создал объект правил доступа для различных компонентов/страниц.
    const rules = {
      articles: {
        create: 'articles:create',
        edit: 'articles:edit'
      }
    }

    и так для проверки каждого требуемого правила, в котором возможна вариативность для разных уровней доступа, формат - компонент + доступные для него действия, но тут по желанию, требуется просто разграничить уникальность по компонентам.

    2. Затем создал объект с уровнями доступа и доступными им правилами, для каждой роли это просто Set в который загоняются доступные действия из правил.

    3. Ну и функция, которая на вход принимает правило и по текущей роли пользователя ищет в Set коллекции это самое правило, нашли - значит доступно, вернули true

    Далее в нужном компоненте дергаем нашу функцию проверки прав, передавая туда правило для проверки доступа. Например, у нас просто обычный юзер залогинился, а не редактор.
    Вызываем checkPermission(rules.articles.edit), если функа вернула false, то блокируем или скрываем кнопку редактирования статьи, ну и т.д.

    Редактирование уровней доступа у нас в одном месте, на это же и редактор в целом написать можно будет отдельный, чтобы в коде не править, ну и хранить в таком формате доступы на бэке тогда и просто присылать на фронт открывая/закрывая/изменяя нужные разделы для определенных ролей и т.д.

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

    @slide13
    frontend/web-developer
    Вангую, что у вас windows. В package.json поменяйте 35ю строку на:
    "build": "SET NODE_ENV=production & webpack --config config/webpack.prod.js",

    У вас команда build под linux написана, для винды надо команды через & разделять + переменная окружения сетится по другому

    В данном случае, если у вас разные ОС можно использовать cross-env пакет, чтобы не приходилось ничего править вручную
    Ответ написан
  • Как протестировать enzyme мини компонент?

    @slide13
    frontend/web-developer
    Через find
    const wrapper = shallow(<Boz/>);
    expect(wrapper.find(MuiBoz)).to.have.lengthOf(1);

    Возможно, потребуется пропы замокать еще через wrapper.setProps
    Ответ написан
    Комментировать
  • Почему так работает useState?

    @slide13
    frontend/web-developer
    Так работает из-за StrictMode в реакте, потому что в этом режиме на этапе разработки Реакт делает дополнительную проверку и делает вызовы некоторых методов дважды (собственно, это и видно в консоли):

    Строгий режим не способен автоматически обнаруживать побочные эффекты, но помогает их отследить, сделав более детерминированными. Такое поведение достигается путём двойного вызова следующих методов:
    1. Методы constructor, render, и shouldComponentUpdate классового компонента
    2. Статический метод классового компонента getDerivedStateFromProps
    3. Тело функционального компонента
    4. Функции обновления (первый аргумент setState)
    5. Функции, переданные в useState, useMemo, или useReducer


    В продакшен сборке будет все ок, можно проверить убрав обертку StrictMode, тогда в теле компонента и в useEffect значение test будет одинаковым и вызываться console.log("component", test); будет только один раз при вводе в инпут.
    Ответ написан
    1 комментарий