Задать вопрос
  • Ошибка Cannot read properties of null (reading 'useContext')?

    michael_mashush
    @michael_mashush
    Дмитрий Перевозкин, я могу ошибаться, давно уже не использую redux, но состояния являются иммутабельными, а чтобы сделать его мутабельным и работал вариант с простым присвоением - используют обертку в виде immer.

    https://redux-toolkit.js.org/usage/immer-reducers#...
    Написано
  • Ошибка Cannot read properties of null (reading 'useContext')?

    michael_mashush
    @michael_mashush
    Разве эта запись будет работать?

    reducers: {
        addArticle(state, action) {
            state.post = state.post.push(action.payload)
        }
    }


    В этом случае в state.post запишется результат выполнения state.post.push, а не новый массив, а результатом пуша является число, обозначающее количество элементов массива.
    Написано
  • При стилизации компонента React не видны scss переменные подключенные модулем к index.js, в чем может быть проблема?

    michael_mashush
    @michael_mashush
    а не может ли быть проблема в импорте файлов? Внутри файла style.scss, который Вы импортируете в index.js, все файлы стилей подключаются с указанием названия файла и расширения, а файл с переменными подключается без расширения. Хотя лично у меня при импорте одного scss-файла в другой автоматически убирается расширение, но мало ли
    Написано
  • Как правильно позиционировать тултип?

    michael_mashush
    @michael_mashush Автор вопроса
    да, все так и делал, но вышло как-то уж больно просто и в некоторых ситуациях тултип позиционировался корректно, но не тогда, когда это было нужно. Завтра буду переделывать)
    Написано
  • Как правильно позиционировать тултип?

    michael_mashush
    @michael_mashush Автор вопроса
    Выглядит сложно, все-таки без огромного количества if никуда, попробую завтра разобраться)
    Написано
  • Как перегрузить React.ForwardRefRenderFunction компонент?

    michael_mashush
    @michael_mashush Автор вопроса
    WbICHA, да, это абсолютно то, что мне было нужно. Код, конечно, ты жесткий написал, я его подогнал под свою задачу, но, кажется, придется найти время и разобрать подробно что ты там написал, ахаха. Можешь закидывать свой коммент в ответы - отмечу решением)
    Написано
  • Как перегрузить React.ForwardRefRenderFunction компонент?

    michael_mashush
    @michael_mashush Автор вопроса
    WbICHA, слушай, вроде это то что нужно, попробую разобрать что ты тут понаписал, в любом случае спасибо!
    Написано
  • Как перегрузить React.ForwardRefRenderFunction компонент?

    michael_mashush
    @michael_mashush Автор вопроса
    Kentavr16, хоспади)

    Вот пишу я такой компонент и в нем есть кнопка. Без перегрузки я бы просто сказал что props: ButtonProps | AnchorProps. Внутри компонента логика бы осталась прежней, но вот что бы произошло снаружи:

    <Button onClick={e => {}} /> 
    // где MouseEvent происходит то ли для HTMLButtonElement, то ли для HTMLAnchorElement
    // и нам нужно будет явно это все дело проверить + атрибут type ничего нам не подскажет
    // поскольку у ссылок тоже есть атрибут type и для компонента он просто станет типа string... ужас


    Перегрузка решает этот вопрос - если я явно не передаю href это 100% кнопка! onClick будет относится к HTMLButtonElement, type будет подсказывать только типы, которые доступны для кнопки. В противном случае - это 100% ссылка, ведь я передал href.

    Зачем нужен ref? Затем же, зачем и все остальное. Цель такова, чтобы работая с кнопкой я не должен был зачем-то проверять будет ли событие клика происходит точно на кнопке, а не на ссылке... бред же?

    Точно также и с ref - если я не передаю параметр href, то это бы означало что я не могу передать в этот компонент ref на ссылку, поскольку компонент работает напрямую с кнопкой.
    Написано
  • Как перегрузить React.ForwardRefRenderFunction компонент?

    michael_mashush
    @michael_mashush Автор вопроса
    Kentavr16, вот есть компонент кнопки, да?) Часто встречается такая ситуация, что кнопка должна выполнять роль ссылки и для этого мы должны проверять props компонента, чтобы понять что рендерить - кнопку или ссылку.

    Зачем нужна перегрузка? Чтобы исходя из переданных в компонент пропсов понимать что нужно отрисовать, но чтобы это работало не только внутри компонента, но и снаружи.

    В данном случае не просто отрисуется кнопка, но и переданные ей пропсы будут иметь отношение непосредственно с элементом button - нам доступны все атрибуты из ButtonProps.

    <Button />

    Здесь же мы передаем параметр href в виде строки и теперь нам доступны все атрибуты из AnchorProps - тот же самый onClick теперь явно взаимодействует с HTMLAnchorElement.

    <Button href="/posts" />

    По сути, весь кусок кода, написанный в вопросе, можно скопировать, вставить и он будет работать, правда нужно скачать "react-router-dom" и можно потыкать это все на практике что конкретно делает перегрузка
    Написано
  • Как перегрузить React.ForwardRefRenderFunction компонент?

    michael_mashush
    @michael_mashush Автор вопроса
    WbICHA, то есть суть в том, что типы ButtonProps и AnchorProps отличаются тем, что для первого недоступен href, а для второго доступен. Теперь, если я НЕ передаю href - мне доступны только атрибуты кнопки, а в противном случае - только атрибуты ссылки. Все просто)
    Написано
  • Как перегрузить React.ForwardRefRenderFunction компонент?

    michael_mashush
    @michael_mashush Автор вопроса
    WbICHA, как это не понятно?) Есть компонент кнопки, который может выступать как кнопкой, так и ссылкой, логично? Логично. Честно сказать, я даже удивлен что Вы не поняли. К тому же в конце я дописал на счет отсутствия ref:

    Но это реализация компонента с помощью FunctionComponent, но сколько я ни пытался - не получается это переписать на ForwardRefRenderFunction, чтобы передаваемые ref зависели от Props


    Есть тип ButtonProps, а есть AnchorProps. Первый нужен для кнопки, а второй для ссылки. Перегрузка решает вопрос того, как этот компонент доступен снаружи:

    <Button /> // это кнопка
    <Button type="button" /> // атрибут type автоматически подскажет мне только нужные значения - button/reset/submit
    <Button onClick={(e) => {}} /> // MouseEvent будет работать для HTMLButtonElement
    
    <Button href="/" /> // это ссылка
    <Button href="/" type="???" /> // это ссылка, но ей я уже не могу перекинуть типы кнопки
    <Button href="/" onClick={(e) => {}} /> // MouseEvent будет работать для HTMLAnchorElement
    Написано
  • Как настроить loader при загрузке данных через get запрос?

    michael_mashush
    @michael_mashush
    Иван Филипов, не за что, потом все-таки посмотрите в сторону библиотеки react-query - очень удобная)
  • Как настроить loader при загрузке данных через get запрос?

    michael_mashush
    @michael_mashush
    Я всегда выношу все запросы в отдельные хуки, где бы располагалось локальное состояние запроса (isLoading, isError, data и прочее) и вызываю их внутри компонента.

    Примерно такого вида:

    function useGetData(...) {
    
      const [ isLoading, setIsLoading ] = React.useState(false)
      const [ isError, setIsError ]     = React.useState(false)
      const [ data, setData ]           = React.useState(null)
    
      async function getData() {
        try {
          setIsLoading(true)
          const data = await fetch(...)
          setData(data)
        } catch (error) {
          setIsError(true)
        } finally {
          setIsLoading(false)
        }
      }
    
      return {
        isLoading,
        isError,
        data
      }
    
    }


    Код самого компонента:

    const Component = () => {
    
      const {
        isLoading,
        isError,
        getData,
        data
      } = useGetData()
    
      if (isLoading) return (<div>Loading...</div>)
      if (isError)   return (<div>Oops...</div>)
      if (data)      return (<div>{data}</div>)
      
      return (
        <button onClick={getData}>
          получить данные
        </button>
      )
    
    }


    А дальше уже если нужно записывать в state/store, то создаешь useEffect на отлов data и как только ты их получаешь - диспатчишь куда требуется. А ещё лучше не городить велосипед и использовать react-query, который позволяет удобно работать с запросами, "оборачивая" их в хуки.

    Надеюсь ответил по теме и чем-нибудь помог
  • Почему этот код ошибки Firebase отсутствует в перечне ошибок?

    michael_mashush
    @michael_mashush Автор вопроса
    Я выделил отдельный тип FirebaseAuthErrorCodes, куда записал актуальные коды ошибок и дополнительно auth/invalid-login-credentials. Но спасибо за ответ)
  • Почему navigate срабатывает в родительском компоненте, но не в дочернем?

    michael_mashush
    @michael_mashush Автор вопроса
    Все что я успел понять за столь недолгой время - дело скорее всего в самом компоненте AuthManager, а точнее в хуке useSubscribeToAuthChange

    useSubscribeToAuthChange

    import React                                 from 'react'
    import { User, getAuth, onAuthStateChanged } from 'firebase/auth'
    import useStoreDispatch                      from 'hooks/store/useStoreDispatch'
    import useStoreSelector                      from 'hooks/store/useStoreSelector'
    import { firebaseApp }                       from 'utils/configs/FirebaseConfig'
    import { userActions }                       from 'store/slices/UserSlice'
    
    type UseSubscribeToAuthChangeReturn = {
      isLoading: boolean
      isSuccess: boolean
      isError:   boolean
      error:     Error | null
      reset:     () => void
    }
    
    function useSubscribeToAuthChange(): UseSubscribeToAuthChangeReturn {
    
      const userState = useStoreSelector((store) => store.userState)
      const dispatch  = useStoreDispatch()
    
      const [ isLoading, setIsLoading ] = React.useState<boolean>(true)
      const [ isSuccess, setIsSuccess ] = React.useState<boolean>(false)
      const [ isError, setIsError ]     = React.useState<boolean>(false)
      const [ error, setError ]         = React.useState<Error | null>(null)
    
      const firebaseAuth = getAuth(firebaseApp)
    
      function reset(): void {
        setIsLoading(true)
        setIsSuccess(false)
        setIsError(false)
        setError(null)
      }
    
      function authChangeHandler(user: User | null): void {
        if (user) {
          dispatch(userActions.signIn({
            uid:         user.uid,
            email:       user.email,
            displayName: user.displayName,
            phoneNumber: user.phoneNumber,
            photoURL:    user.photoURL,
            providerId:  user.providerId
          }))
        }
    
        if (!user && userState.isAuthorized) {
          dispatch(userActions.signOut())
        }
    
        setIsLoading(false)
        setIsSuccess(true)
      }
    
      function authErrorHandler(error: Error): void {
        setIsError(true)
        setError(error)
      }
    
      React.useEffect(() => {
        const unsubscribe = onAuthStateChanged(firebaseAuth, authChangeHandler, authErrorHandler)
        return unsubscribe
      }, [firebaseAuth]) // eslint-disable-line react-hooks/exhaustive-deps
    
      return {
        isLoading,
        isSuccess,
        isError,
        error,
        reset
      }
    
    }
    
    export default useSubscribeToAuthChange

  • По какой причине реакт не воспринимает массив?

    michael_mashush
    @michael_mashush
    WbICHA, ну так я и написал что не вижу проблем, но на всякий случай указал про импорт. Только что проверил - действительно any, да и к тому же там ошибку выдает что useState is not defined, так что думаю да, импорт уж точно тут не причем)
  • Почему JS выдает синтаксическую ошибку на JSX?

    michael_mashush
    @michael_mashush
    igreklpofrss, отличный ролик для ознакомления с React для начинающих. Учитывая то, что Вам в любом случае нужно будет разобраться с тем, как работает node.js - это будет определённо полезно)
  • Почему JS выдает синтаксическую ошибку на JSX?

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

    Поэтому сразу советую просто разобрать как создать именно React приложение через:



    Советую сначала ознакомиться именно с первым вариантом - разобраться можно будет за один вечер как все это устроено и как все это собирается, интернет в помощь, на ютубе большое количество интересных роликов есть.

    На счет того, можно ли использовать .js файлы вместе с .jsx - да, можно, но опять-таки - начните лучше с создание React приложений через те способы, которые я перечислил выше, а не через обычное подключение через скрипты))
  • Почему JS выдает синтаксическую ошибку на JSX?

    michael_mashush
    @michael_mashush
    дополню еще то, что Вы скорее всего читаете старую документацию, поскольку у React есть новая документация, где Ваш пример будет выглядеть иначе:

    import { createRoot } from 'react-dom/client';
    
    // Clear the existing HTML content
    document.body.innerHTML = '<div id="app"></div>';
    
    // Render your React component instead
    const root = createRoot(document.getElementById('app'));
    root.render(<h1>Hello, world</h1>);