首页 > 解决方案 > 尝试使用组件时 React 中的无限加载屏幕

问题描述

我正在尝试将汉堡菜单添加到我现有的实时聊天应用程序中。我已经在 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 && <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 wrap 放在 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>
    )

现在我想要的汉堡包原件中的所有项目都开始放在一边,但是一旦我尝试传递<FarSdieBar />到 Burger.js 以完成功能,我就会得到无限加载屏幕。这是完整的代码:

汉堡.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 **/

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

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

    &: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 && <Icon className="farSidebarOption_icon"/>}
            {Icon ? (
                
                <h3> {title} </h3>
                
            ): (
                <h3 className="farSidebarOption__channel">
                   <span className="farSidebarOption__hash"># {title}</span>
                </h3>
                
            )}
        </div>
    )
}

export default FarSideBarOption

标签: reactjs

解决方案


推荐阅读