• Почему при клике на навигацию не меняется id?

    michael_mashush
    @michael_mashush
    Я так понимаю Вам просто нужно подсвечивать активную ссылку? Можно написать так:

    const Navigation: React.FunctionComponent = () => {
    
      const routeList: RouteItem[] = [
        { name: 'Главная', path: '/' },
        { name: 'Оценки',  path: '/grade' }
      ]
    
      function getClassName({ isActive }: { isActive: boolean }): string {
        return `${styles.link} ${isActive ? styles.active : 0}`
      }
    
      return (
        <ul className={styles.list}>
          {
            routeList.map((route) => (
              <li key={route.path} className={styles.item}>
                <NavLink to={route.path} className={getClassName} data-scroll>
                  {route.name}
                </NavLink>
              </li>
            ))
          }
        </ul>
      )
    
    }


    Библиотека react-router-dom предоставляет компоненты Link и NavLink, где второй может принимать в качестве className функцию, которая принимает такие параметры как isActive, isPending и т.п.

    Так что состояние тут явно лишнее, как и обработка клика по элементам li)

    upd:

    Чтобы не заморачиваться с длинными именами классов - установите маленькую библиотеку classnames:

    function getClassName({ isActive }: { isActive: boolean }): string {
        return classNames(styles.link, {
          [styles.active]: isActive
        })
      }


    upd 2:

    Клик на элементе списка может некорректно обрабатываться из-за внутреннего устройства компонента Link, поэтому если Вам так необходимо использовать состояние categoryId, то событие клика нужно вешать на сам компонент Link. Но костылем это быть не перестанет)
    Ответ написан
  • Как реализовать анимацию смещения текста кнопки?

    michael_mashush
    @michael_mashush
    Если бы не нужно было анимировать каждый символ отдельно - можно было бы попробовать сделать через ::before и ::after, куда в правило content запихиваешь содержимое кнопки. ::before позиционируем таким образом, чтобы мы его видели в центре кнопки, а ::after за его пределами. При наведении на кнопку ::before уводишь наверх, а ::after выводишь на середину кнопки.

    Если же нужно обязательно анимировать посимвольно - проделываешь тот же самый алгоритм, но уже без ::before и ::after, а делая на вложенных элементах, типа такого:

    <button class="button">
      <div class="button-primary-text">
        <span class="button-symbol">D</span>
        <span class="button-symbol">O</span>
        <span class="button-symbol">N</span>
        <span class="button-symbol">A</span>
        <span class="button-symbol">T</span>
        <span class="button-symbol">E</span>
      </div>
      <div class="button-secondary-text">
        <span class="button-symbol">D</span>
        <span class="button-symbol">O</span>
        <span class="button-symbol">N</span>
        <span class="button-symbol">A</span>
        <span class="button-symbol">T</span>
        <span class="button-symbol">E</span>
      </div>
    </button>


    По идее стили будут несложные, через :nth-child задать некоторые задержки для символов внутри кнопки, а сам текст двигать с помощью transform: translate(...)

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

    michael_mashush
    @michael_mashush
    Точно так и не понял в чем у Вас заключается проблема, но лично у меня данный код работает. Попробуйте его написать таким образом:

    import React from 'react'
    
    export type CommentItem = {
      id: number
      comment: string
      createdComment: any
      // eslint ругается на тип "any"
      // лучше от него потом избавиться
    }
    
    export type CommentList = CommentItem[]
    
    const Comment = () => {
    
      const [comments, setComments] = React.useState<CommentList>([])
     
      return (
        <div>
          {/* 
            для comment-объекта можно не устанавливать тип, поскольку 
            среда разработки поймёт что это объект массива с типом CommentList (то есть CommentItem)
          */}
          {comments.map((comment) => (
            <>
              <p>{comment.id}</p>
              <p>{comment.comment}</p>
              <p>{comment.createdComment}</p> 
            </>
          ))}
        </div>
      )
    
    }
    
    export default Comment


    У Вас точно импортирован хук useState?
    Ответ написан
  • От чего зависит куда будет зумиться сайт при ctrl + колёсико мыши? Так же как отключить зум на колесо мыши + ctrl?

    michael_mashush
    @michael_mashush
    А зачем вообще нужна данная фича? Знаю только про этот метод, но как я понимаю он работает только на мобильных устройствах, да и в целом не совсем то, что нужно:

    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />


    Могу ошибаться, но раз вы решили задать этот вопрос здесь - поиски в интернете Вас ни к чему не привели. Вам ничего мешает написать код, который бы просто убирал действие по умолчанию для события "mousewheel", но по найденной мне информации - эту фичу как минимум Chrome блокирует.
    Ответ написан
  • Как добавлять вложенности типов?

    michael_mashush
    @michael_mashush
    Судя по представленному коду я могу предположить что Вы вообще не разобрались в React с обычным JavaScript и решил использовать сразу его с TypeScript. JSX код действительно крайне странный, но даже если учитывать этот факт - не понимаю о какой вложенности типов идет речь)

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

    У React же имеется отличная обновленная документация, где сразу после небольшой теории ты можешь на практике последовательно сделать небольшую игру "Крестики-Нолики".

    Типы - это просто надстройка над обычным JavaScript, где ты описываешь то, с какими данными ты сейчас работаешь и что они содержат.

    В данном случае я попробую угадать что вы имели ввиду:

    type Slide = {
      img: string;
      alt: string;
    }
    
    type Slider = {
      data: Slide[]; // data - массив объектов типа Slide
    }
    Ответ написан
    1 комментарий
  • Как правильно задать аргумент в компонент?

    michael_mashush
    @michael_mashush
    1. Компонент Box, который принимает как props развернутый объект box:

    type Box = {
      name: string;
      date: string;
      image: string;
    };
    
    // можно сразу указать что props будет иметь тип Box, но я так не привык делать
    // всегда описываю тип Props для объекта props
    type Props = Box;
    
    export default function Box(props: Props) {
      const {name, date, image} = props;
    }


    И передавать в него данные нужно следующим образом:

    {data.map((box) => (
      <Box
        name={box.name}
        date={box.date}
        image={box.image}
      />
    ))}


    Или можно делать так, но это не везде принято делать, поскольку читаемость понижается (опять-таки все это условно, делай как считаешь нужным):

    {data.map((box) => (
      // поля объекта box сразу стали полями props
      // и про key не забудь внутри цикла map
      <Box key={?} {...box} />
    ))}


    2. Компонент Box, который принимает как props обычный объект, где box является вложенным объектом:

    type Box = {
      name: string;
      date: string;
      image: string;
    }
    
    type  Props = {
      box: Box;
    };
    
    export default function Box(props: Props) {
      const {name, date, image} = props.box;
    }


    и передавать его можно таким способом:

    {data.map((box) => (
      // объект box передается как props.box
      // и про key не забудь внутри цикла map
      <Box key={?} box={box} />
    ))}


    В большинстве случаев лучше использовать первый вариант, поскольку так легче использовать React.memo (если его, конечно, нужно использовать).
    Ответ написан
    1 комментарий
  • Селекторы в CSS?

    michael_mashush
    @michael_mashush
    Дополню комментарий Максим:

    1. Для всех элементов li внутри ul.menu (любая вложенность):
    ul.menu li {
        // code
    }


    2. Для всех элементов li непосредственно внутри ul.menu (первый уровень вложенности):
    ul.menu > li {
        // code
    }


    Да и что подразумевается вообще под фразой? Порядок селекторов?:

    как правильно записать порядок

    Как-то неточно сформулировано)
    Ответ написан
    Комментировать