#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); }, []);