Бесконечный экран загрузки в React при попытке использовать компонент

#reactjs

#reactjs

Вопрос:

Я пытаюсь добавить меню гамбургеров в мое существующее приложение для чата. Я завернул то, что я хочу, чтобы было внутри меню гамбургера в FarSideBar.js в возврате он завернут в ‘Ul’. Теперь в моем Burger.js Мне нужно использовать <FarSideBar open={open} /> компонент, но как только я вообще использую FarSideBar, я получаю бесконечный экран загрузки. Я также оставлю код для FarSideBarOption.js поскольку я изначально пытался реализовать это в этом файле с Burger.js и функциональность работала, но единственное, что изменилось, когда я нажал на бургер, был первый хэштег, потому что он был настроен таким образом в возврате:

  return (
        <div className="farSidebarOption" onClick={addChannelOptions ? addChannel : selectChannel}>
            <Ul open={open}>
            {Icon amp;amp; <Icon className="farSidebarOption_icon"/>}
            {Icon ? (
                
                <h3> {title} </h3>
                
            ): (
                <h3 className="farSidebarOption__channel">
                   <span className="farSidebarOption__hash"># {title}</span>
                </h3>
                
            )}
            </Ul>
        </div>
    )
  

и Burger.js выглядело так:

 const Burger = () => {
  const [open, setOpen] = useState(false)
  
  return (
    <>
      <StyledBurger open={open} onClick={() => setOpen(!open)}>
        <div />
        <div />
        <div />
      </StyledBurger>
      <FarSideBarOption open={open}/>
    </>
  )
}
  

Итак, я переключился на перенос Ul в FarSideBar.js:

  return (
        <div className="farSidebar">
            <div className="farSidebar__header">
                <div className="farSidebar__header__info">
                    <h2 >Discord</h2>
                    <h1 className="farSideBar__header__info__hamburger"><Burger /></h1>
                    <h3>
                        {user?.displayName}
                    </h3>

                        

                </div>
                <Ul open={open}>
                        <FarSideBarOption  title="myself"  Icon={AlarmOnIcon}/>
                        <FarSideBarOption  title="wow"  Icon={AlarmOnIcon}/>
                        <FarSideBarOption  title="add"  Icon={AlarmOnIcon} addChannelOptions/>
                
                
                {channels.map(channel => (
                    <FarSideBarOption title={channel.name} id={channel.id} />
                ))}
                </Ul>
            </div>
        </div>
    )
  

И теперь все элементы, которые я хочу в оригиналах hamburger, начинаются сбоку, но как только я пытаюсь перейти <FarSdieBar /> в Burger.js для завершения функциональности я получаю экран бесконечной загрузки. Вот полный код:

Burger.js

 import React, { useState } from 'react';
import styled from 'styled-components';
import FarSideBarOption from './FarSideBarOption.js';
import FarSideBar from './FarSideBar';

const StyledBurger = styled.div`
  width: 2rem;
  height: 2rem;
  position: fixed;
  top: 15px;
  right: 20px;
  z-index: 20;
  display: none;

  @media (max-width: 768px) {
    display: flex;
    justify-content: space-around;
    flex-flow: column nowrap;
  }

  div {
    width: 2rem;
    height: 0.25rem;

    /* Hamburger symbol color change */
    background-color: ${({ open }) => open ? '#ccc' : '#333'};

    border-radius: 10px;
    transform-origin: 1px;
    transition: all 0.3s linear;


  /** Hamburger symbol animation **/

    amp;:nth-child(1) {
      transform: ${({ open }) => open ? 'rotate(45deg)' : 'rotate(0)'};
    }

    amp;:nth-child(2) {
      transform: ${({ open }) => open ? 'translateX(100%)' : 'translateX(0)'};
      opacity: ${({ open }) => open ? 0 : 1};
    }

    amp;:nth-child(3) {
      transform: ${({ open }) => open ? 'rotate(-45deg)' : 'rotate(0)'};
    }

  }
`;

const Burger = () => {
  const [open, setOpen] = useState(false)
  
  return (
    <>
      <StyledBurger open={open} onClick={() => setOpen(!open)}>
        <div />
        <div />
        <div />
      </StyledBurger>
      <FarSideBar open={open}/>
    </>
  )
}

export default Burger
  

FarSideBar.js

 import React, {useState, useEffect} from 'react'
import { useStateValue } from "../StateProvider";
import db from '../firebase';
import FarSideBarOption from '../components/FarSideBarOption';
import { AlarmOnIcon }  from '@material-ui/icons/AlarmOn';
import '../CSS/main.scss'
import Burger from './Burger'
import styled from 'styled-components';

const FarSideBar = ({ open }) => {
  

    const Ul = styled.ul`

    @media (max-width: 768px) {
      background-color: #0D2538;
      transform: ${({ open }) => open ? 'translateX(0)' : 'translateX(110%)'};
      top: 0;
      right: 0;
      transition: transform 0.3s ease-in-out;
      color: #fff;
      overflow-x: hidden;
    }
  `;

    const [channels, setChannels] = useState([]);
    const [{ user }] = useStateValue();
    
    useEffect(() => {
        db.collection('rooms').onSnapshot(snapshot => (
            setChannels(
                snapshot.docs.map(doc =>
                    ({
                        id: doc.id,
                        name: doc.data().name
                    }))
            )
        ))
    }, [])

    return (
        <div className="farSidebar">
            <div className="farSidebar__header">
                <div className="farSidebar__header__info">
                    <h2 >Discord</h2>
                    <h1 className="farSideBar__header__info__hamburger"><Burger /></h1>
                    <h3>
                        {user?.displayName}
                    </h3>

                        

                </div>
                <Ul open={open}>
                        <FarSideBarOption  title="myself"  Icon={AlarmOnIcon}/>
                        <FarSideBarOption  title="wow"  Icon={AlarmOnIcon}/>
                        <FarSideBarOption  title="add"  Icon={AlarmOnIcon} addChannelOptions/>
                
                
                {channels.map(channel => (
                    <FarSideBarOption title={channel.name} id={channel.id} />
                ))}
                </Ul>
            </div>
        </div>
    )
}

export default FarSideBar

  

FarSideBarOption.js

 import React from 'react'
import '../CSS/main.scss'
import { useHistory } from "react-router-dom";
import db from '../firebase';
import styled from 'styled-components';



function FarSideBarOption({ id, title, addChannelOptions, Icon} ) {


    const history = useHistory();


    const selectChannel = () => {
        if(id) {
            history.push(`/room/${id}`)
        } else {
            history.push(title);
        }
    }

    const addChannel = () => {
        const channelName = prompt('Please enter the channel name')

        if (channelName) {
            db.collection('rooms').add({
                name: channelName
            })
        }
    }


    return (
        <div className="farSidebarOption" onClick={addChannelOptions ? addChannel : selectChannel}>
            {Icon amp;amp; <Icon className="farSidebarOption_icon"/>}
            {Icon ? (
                
                <h3> {title} </h3>
                
            ): (
                <h3 className="farSidebarOption__channel">
                   <span className="farSidebarOption__hash"># {title}</span>
                </h3>
                
            )}
        </div>
    )
}

export default FarSideBarOption
  

Комментарии:

1. Выполняет ли db.collection в FarSideBar.js (useEffect()) должен быть асинхронным?

2. Куда бы я поместил aysnc / await в useEffect, чтобы протестировать его?

3. это может помочь medium.com/javascript-in-plain-english /…

4. Я читал об использовании async с useEffect, и это имеет смысл. Проблема в том, что я не знаю, куда его поместить в эту функцию, поскольку все, что я прочитал, включало установку async / await сразу после присвоения имени const. db.collection настроен не так

5. Например useEffect(async () => { const users = await axios.get("https://randomuser.me/api/?page=1amp;results=10amp;nat=us"); setUsers(users.data.results); }, []);