• Почему JS-функция, останавливает выполнение после первого абзаца?

    @slide13
    frontend/web-developer
    childNodes включает не только элементы, но и тексты, комментарии, переносы строк. После парсинга p элементы находятся внутри текстовых переносов строк /n, поэтому когда производится проверка if ( e.nodeType !== Node.ELEMENT_NODE ) return; они игнорируются. Так что если требуется перебрать только элементы всегда нужно использовать children, а не childNodes. В данном случае все переносы строк буду проигнорированы и элементы p преобразуются как нужно.

    function testFn(node) {
      for (const child of node.children) {
        testFn(child);
        if ( child.nodeName !== 'LI' ) {
          child.replaceWith( ...child.childNodes );
        }
      }
    }
    Ответ написан
    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 комментарий
  • Почему фиксированный блок перемещается при прокрутке?

    @slide13
    frontend/web-developer
    HitGirl объясню в чем проблема. Да, фиксированный элемент фиксируется относительно вьюпорта браузера и остается фиксированным при скролле, но в данном случае у вас у родителя (container) установлено свойство container-type: inline-size;
    но при установке некоторых свойств они влияют на фиксированно спозиционированные элементы и те становятся позиционируемыми относительно родительского элемента, устанавливающего это свойство, т.е. в данном случае родителя (container) и больше не являются фиксированными относительно вьюпорта браузера.

    Вот список всех таких свойств:
    filter
    transform
    backdrop-filter
    perspective
    contain
    container
    transform-style
    content-visibility

    container и в частности container-type в принципе не стоит использовать пока, т.к. 76% всего глобальная поддержка.
    В данном случае заменить fixed элемент на sticky самое простое, как вы и сделали. Альтернативный вариант через js получить ширину container и установить ее для mobileSidebar, если требуется иногда прям fixed оставить
    Ответ написан
    3 комментария
  • Когда в рамке находится фото и текст, текст себя старанно ведет?

    @slide13
    frontend/web-developer
    Самый старый и простой метод - float:
    .tab img {
        height: 200px;
        float: left;
    }

    Но лучше tab сделать флекс контейнером и потом уже позиционировать внутри элементы как угодно, но в данном случае больше ничего и не нужно:

    .tab {
        outline: 5px solid red;
        width: 80%;
        height: 200px;
        margin-bottom: 10px;
        display: flex;
    }
    Ответ написан
    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 комментария
  • Как сделать скролл у flex-контейнера?

    @slide13
    frontend/web-developer
    Баг ли это или так и было задумано, но с justify-content: flex-end и скроллом во всех браузерах есть проблемы и в одном контейнере они вместе не работают.
    Самое простое решение (на мой взгляд) - это перенести скролл в контейнер выше.

    вот пример: https://codepen.io/slide13/pen/VwrrOeE
    Ответ написан
    Комментировать
  • Как настроить разделение ролей (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
    Ответ написан
    Комментировать
  • Как вытащить значение по ключу из вложенного объекта?

    @slide13
    frontend/web-developer
    usersList.forEach(user => console.log(user.company.name))
    Ответ написан
    Комментировать
  • Почему так работает 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 комментарий
  • Как получить значение switch в vkui?

    @slide13
    frontend/web-developer
    Также, как и с обычным input type="checkbox" в реакт - либо передаете значение checked в компонент сами и функцию onChange для изменения этого значения, либо через ref, что в данном случае проще будет

    Документация
    Ответ написан
    Комментировать
  • Рандомное число в диапазоне с равным шансом выпадения?

    @slide13
    frontend/web-developer
    Вот ответ с MDN

    function getRandomIntInclusive(min, max) {
      min = Math.ceil(min);
      max = Math.floor(max);
      return Math.floor(Math.random() * (max - min + 1) + min);
    }
    Ответ написан
    3 комментария
  • Почему возвращает Failed to fetch?

    @slide13
    frontend/web-developer
    Подозреваю, что проблема в https и запрос на http://localhost:5000/add-user/ будет работать. Для https нужен ssl сертификат, а в коде сервера не вижу создания https сервера.
    Ответ написан
    Комментировать
  • Почему данные из localstorage отображаются при переходе на другую страницу со 2 раза?

    @slide13
    frontend/web-developer
    Отправка запроса на сервер это асинхронная операция, а вы делаете переход на "/metric" сразу же после начала отправки запроса, не дожидаясь его выполнения. Поэтому вначале осуществляется переход на другой роут, а потом записываются данные в localStorage, следовательно они и начинают отображаться после повторного захода на "/metric"
    Ответ написан
    Комментировать
  • Как в react передать функции новое состояние?

    @slide13
    frontend/web-developer
    Вариант по сути только один, наверное - сохранять состояние в ref.

    Но все равно придется обновлять ref в useEffect:
    useEffect(() => {
        ref.current = status;
      }, [status]);

    Из ref уже читать статус в вашей функции getStatus, где ref.current будет содержать всегда последнее значение status.
    Ответ написан