Я столкнулся с проблемой при написании простой панели навигации и выпадающего меню в React. Я создал раздел в навигационной панели для учетной записи, которая при наведении на нее приведет к появлению выпадающего меню сразу под ним. Я попытался скопировать код для этого непосредственно с сайта w3, но столкнулся с большим количеством проблем и решил использовать свой собственный подход ...
Я создал функциональный компонент Dropdown, отображаемый моим компонентом Navbar. Видимое / скрытое состояние компонента Dropdown отслеживается в переменной useState с именем hideDropdown.
До этого момента все работало правильно. Моя проблема возникает при попытке настроить этот выпадающий компонент под разделом учетной записи на панели навигации. Независимо от того, что я пытаюсь, я не могу получить его в нужном месте на экране. Даже если я жестко закодирую количество пикселей, что компонент должен быть с левой стороны, изменение размера экрана разрушает это. По умолчанию компонент Dropdown появляется слева. Кроме того, только свойство left влияет на его положение. Право не делает ничего наблюдаемого. Кроме того, проценты, по-видимому, не основаны на ширине страницы, так как для выравнивания раскрывающегося списка полностью справа свойство left должно быть 800%.
https://codepen.io/sjh5888/pen/rNaJgya
Navbar. js
import React, { useState, useContext, useEffect } from "react";
import { Redirect } from "react-router-dom";
import jsonwebtoken from "jsonwebtoken";
import Dropdown from "./Modals/Dropdown";
import "./CSS/navbar.css";
import NewPostModal from "./Modals/NewPostModal";
import { CategoryContext } from "./Context/CategoryContext";
function Navbar(props) {
const { categories, setCategories, user } = useContext(CategoryContext);
const [modalOpen, updateModal] = useState(false);
const [hideDropdown, setHideDropdown] = useState(false); //change to true when done
const [isLoading, setIsLoading] = useState(true);
const jwtDecoded = jsonwebtoken.decode(localStorage.getItem("jwt"));
console.log(
"is token valid? " +
(jwtDecoded.exp > (Date.now() - (Date.now() % 1000)) / 1000)
);
console.log(jwtDecoded);
if (jwtDecoded.exp > (Date.now() - (Date.now() % 1000)) / 1000) {
return (
<div style={{ zIndex: "1", position: "fixed", display: "flex" }}>
<ul className="navinator">
<li className="navElement">
<a className="anchor" href="/home">
Home
</a>
</li>
<li className="navElement">
<a className="anchor" href="/profile">
Profile
</a>
</li>
<li className="active">
<a
className="anchor"
// href="#"
onClick={e => updateModal(true)}
>
+ New Post
</a>
</li>
<li style={{ float: "right" }}>
<div
id="profile"
onMouseOver={e => setHideDropdown(false)}
onMouseLeave={e => setHideDropdown(true)}
>
<div style={{ float: "left", paddingRight: "10px" }}>
<img
src={user.profileImage}
alt="error"
className="profile-image"
/>
{/* need profileImage field for user */}
</div>
<div style={{ float: "left", paddingRight: "5px" }}>
{jwtDecoded.sub}
</div>
<div style={{ float: "left" }} className="arrow-down"></div>
</div>
</li>
</ul>
<NewPostModal show={modalOpen} updateModal={updateModal} />
<div style={{float:"right"}}><Dropdown visible={hideDropdown} setHideDropdown={setHideDropdown}/></div>
</div>
);
} else {
console.log("redirecting");
return <Redirect to={{ pathname: "/login", state: { from: "/home" } }} />;
}
} //class
export default Navbar;
Выпадающий список. js
import React from "react";
import "../CSS/navbar.css";
export default function Dropdown(props) {
return (
<div
hidden={props.visible}
className="dropdown"
onMouseOver={e => props.setHideDropdown(false)}
onMouseLeave={e => props.setHideDropdown(true)}
>
<li>
<a className="anchor" style={{ textAlign: "left" }} href="/profile">
Profile
</a>
</li>
</div>
);
}
Navbar . css
.navinator {
z-index: 1;
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: rgb(218, 10, 10);
position: fixed;
top: 0;
width: 100%;
height: 52px;
}
.navElement {
float: left;
}
.anchor{
display: block;
color: white !important;
text-align: center;
padding: 14px 16px;
text-decoration: none !important;
cursor: pointer;
}
.anchor:hover {
background-color: rgb(255, 23, 15) !important;
}
.active {
background-color: rgb(28, 13, 110) !important;
float: right;
width: 120px;
}
.active .anchor{
align-items: center;
justify-content: center;
}
.active .anchor:hover {
background-color: rgb(32, 11, 156) !important;
}
.profile-image {
width: 30px;
height: 30px;
position: relative;
overflow: hidden;
border-radius: 50%;
}
#profile {
color: white !important;
text-align: center;
padding: 14px 16px;
text-decoration: none !important;
/* height: 52px; */
overflow: auto;
}
#profile:hover {
background-color: rgb(255, 23, 15) !important;
cursor: pointer;
}
.arrow-down {
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 5px solid white;
margin-top: 10px;
}
.dropdown{
top: 52px;
width: 222px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
display: inline-block;
background-color: rgb(218, 10, 10);
}
.dropdown li{
list-style-type: none;
}
Я довольно новичок в веб-разработке и получаю массу удовольствия. Однако, это немного расстраивает, так как я чувствую, что это должно быть довольно простое решение. Любая помощь будет оценена!