React mouseEnter event not working when on mapped children - javascript

I just want these child elements to show a remove button on mouseover...
console logging in handleMouseEnter shows that on render, ALL children fire the mouseEnter event. it seems stuck in a loop. debugging is next to impossible.
problems only arise when onMouseEnter and onMouseLeave are left in the code.
render(){
const handleMouseEnter = (tool) => this.setState({display : tool});
const handleMouseLeave = () => this.setState({display : "none"});
return (
<div>
<div className="search-result-background">
<div className="search-result-row row">
<div className="col-md-4">
</div>
<div className="col-md-4">
<form>
<TextFieldGroup className="find-tool-search-bar"
onChange= {this.checkToolExists}
value = {this.state.toolname}
field = 'toolname'
label = ''
error = {this.state.errors}
placeholder = "FIND IN FAVORITES"
/>
</form>
</div>
<div className="col-md-4">
<ButtonToolbar>
<DropdownButton noCaret onSelect={this.sort} bsSize="large" title="Sort by" id="dropdown-size-large">
<MenuItem eventKey="1">Name</MenuItem>
<MenuItem eventKey="2">Uploaded Date</MenuItem>
</DropdownButton>
</ButtonToolbar>
</div>
<h1 className="search-error">{this.state.errors}</h1>
<div className="col-md-12" >
{this.state.filteredTools.map((tool,i)=>
<div key ={i} className={"child " + tool.toolname } onMouseEnter={handleMouseEnter(tool.toolname)}
onMouseLeave={handleMouseLeave}> {this.state.display == tool.toolname ?
<button >remove?</button> : null}
<Link to={`/tools/${tool.id.substring(4)}`}>
<Thumbnail
className="thumb" src={logoImagePurple} alt="242x200">
<h3>{tool.toolname}</h3>
</Thumbnail>
</Link>
</div>
)}
</div>
</div>
</div>
</div>
)
}
}

The problem is this line:
onMouseEnter={handleMouseEnter(tool.toolname)}
You should change it to:
onMouseEnter={() => handleMouseEnter(tool.toolname)}

Related

Why does my id i get from next js router.query return undefined on refresh? [duplicate]

This question already has answers here:
useRouter/withRouter receive undefined on query in first render
(9 answers)
Closed 5 months ago.
I am using the id gotten from next router.query to render elements dynamically it works when i access the room from next/link but when i refresh the page it throws this error
here is my code (note: roomId here was gotten from const {roomId} = router.query):
return (
<>
<div className={styles.header}>
<div className={styles.title}>{rooms[roomId].name}</div>
<div className={styles.headerCon}>
<div className={styles.roomUsers}>
<AvatarGroup
max={3}
total={Object.keys(rooms[roomId].users).length}
>
{Object.keys(rooms[roomId].users).map((user) => (
<Avatar
key={user + Math.random()}
alt={users[user].name}
src={users[user].profile_pic}
/>
))}
</AvatarGroup>
</div>
<div className={styles.headerIcons}>
<div className={styles.react}>
<AddReactionOutlinedIcon />
</div>
<div className={styles.notif}>
<NotificationsNoneOutlinedIcon />
</div>
<div className={styles.more}>
<MoreHorizOutlined />
</div>
</div>
</div>
</div>
{user.name === rooms[roomId].createdBy.name ? (
<div className={styles.begin}>
{!roomActive ? (
<button onClick={handleStartSession}>Start</button>
) : (
<button onClick={handleEndSession}>End</button>
)}
</div>
) : (
""
)}
<div className={styles.participators}>
<div className={styles.pAvatars}>
<Avatar
alt={rooms[roomId].createdBy.name}
src={rooms[roomId].createdBy.profile_pic}
/>
<div className={styles.userName}>{rooms[roomId].createdBy.name}</div>
<div className={styles.userRole}>Admin</div>
<div>
<audio autoPlay ref={userAudio} />
{peers.map((peer, index) => {
return <Audio key={index} peer={peer} />;
})}
</div>
</div>
{Object.keys(rooms[roomId].users)
.filter((user) => users[user].name !== rooms[roomId].createdBy.name)
.map((user) => (
<div className={styles.pAvatars} key={Math.random() + user}>
<Avatar alt={users[user].name} src={users[user].profile_pic} />
<div className={styles.userName}>{users[user].name}</div>
<div className={styles.userRole}>Admin</div>
</div>
))}
</div>
</>
);
}
As you can see much of what i am rendering on this page depends on that id, so can someone please help?
You try to access the query parameter before its state is ready. There is a workaround to solve this problem.
import { useRouter } from 'next/router';
const router = useRouter();
useEffect(() => {
if (router.isReady) {
// Do your stuff
// for example: assign query param to a state
}
}, [router.isReady]);

how to use DOM element in React

I want to do getElementById to give css effect and click to slide function.
how do I use DOM in react? Thank you in advance.
function Auth() {
//this part needs to be fixed
const signUpButton = document.getElementById('signUp');
const signInButton = document.getElementById('signIn');
const container = document.getElementById('body');
signUpButton.addEventListener('click', () =>
container.classList.add('right-panel-active'));
signInButton.addEventListener('click', () =>
container.classList.remove('right-panel-active'));
Here are the classnames that might help you understand my code better.
return (
<div className ="auth">
<div className="body" id="body">
<SignUp className="test" />
<SignIn className="test" />
<div className="slide__body">
<div className="slides">
<div className="slide SignUp__left">
<p>Already have an account?</p>
<button className="slide__btn" id='signUp' > Sign In </button>
</div>
<div className="slide SignIn__right">
<p>Not a Member?</p>
<button className="slide__btn" id='signIn' > Sign Up </button>
</div>
</div>
</div>
</div>
</div>
)
}
I guess the propose to use React is that fact you should interact in the component state.
I suggest you use State in your component and add some according to some interaction
function App() {
const [mode, setMode] = React.useState();
const handleMode = (mode) => {
setMode(mode);
};
const containerClasses =
mode === "signUp" ? "body right-panel-active" : "body";
return (
<div className="auth">
<div className={containerClasses} id="body">
<SignUp className="test" />
<SignIn className="test" />
<div className="slide__body">
<div className="slides">
<div className="slide SignUp__left">
<p>Already have an account?</p>
<button
className="slide__btn"
id="signUp"
onClick={() => handleMode("signIn")}
>
{" "}
Sign In{" "}
</button>
</div>
<div className="slide SignIn__right">
<p>Not a Member?</p>
<button
className="slide__btn"
id="signIn"
onClick={() => handleMode("signUp")}
>
{" "}
Sign Up{" "}
</button>
</div>
</div>
</div>
</div>
</div>
);
}
You should avoid direct modification of the dom in React. React assumes that it is the only piece of code modifying the dom, and so it won't know about any changes you make. This opens up the possibility of bugs where react changes something on the dom that you don't expect, or doesn't change something you do expect. A simple piece of code like yours won't have these bugs, but best to learn the react way now so you don't run into these issues with more complicated code.
The react way to do this is to pass onClick props to the elements that need it, and to have a state variable which controls the class names. For example:
import React, { useState } from 'react';
function Auth() {
const [showPanel, setShowPanel] = useState(false);
return (
<div className="auth">
<div className={showPanel ? "body right-panel-active" : "body"}>
<SignUp className="test" />
<SignIn className="test" />
<div className="slide__body">
<div className="slides">
<div className="slide SignUp__left">
<p>Already have an account?</p>
<button
className="slide__btn"
onClick={() => setShowPanel(false)}
>
Sign In
</button>
</div>
<div className="slide SignIn__right">
<p>Not a Member?</p>
<button
className="slide__btn"
onClick={() => setShowPanel(true)}
>
Sign Up
</button>
</div>
</div>
</div>
</div>
</div>
);
}

Make onclick inside onclick in ReactJS

Hi guys I try to make onclick inside onclick, can I run clickdelete() without handleClick().
This is my code
<div
className="row-queue"
key={index}
onClick={() => handleClick(item, index)}
style={
index === myvideoIndex ? playingcolor : playingcolor2
}
>
<div className="column1-queue">{index + 1}</div>
<div className="column2-queue">{item.title}</div>
<div className="column3-queue">{item.singer}</div>
<div className="column4-queue">
<button
onClick={() => clickdelete(index)}
className="btn-delete"
>
<i className="fa fa-trash"></i>
</button>
</div>
</div>
Hope you guys understand what I'm asking :D
// Get a hook function
const {useState} = React
const Example = ({title}) => {
const [count, setCount] = useState(0);
return (
<div>
<div onClick={() => alert('parent')}>
With => e.stopPropagation();
<button onClick={(e) => {
e.stopPropagation();
alert('clicked button')
}}>
Click me
</button>
</div>
<div onClick={() => alert('parent')}>
Without => e.stopPropagation();
<button onClick={(e) => {
alert('clicked button')
}}>
Click me
</button>
</div>
</div>
);
};
// Render it
ReactDOM.render(
<Example title="Example using Hooks:" />,
document.body
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
yes it's possible use event.stopPropagation() so that event will not propagate to our parent div click handler.
<button onClick={(e) => {
e.stopPropagation()
clickdelete(index)
}} className="btn-delete">
<i className="fa fa-trash"></i>
</button>;

Several ternary operators nested within

There is a syntax error {} when I added {this.state.items && this.state.items.length? under <div className =" container ">. When I remove this extreme condition {this.state.items && this.state.items.length? : Components : <Preloader />everything works.A lot of nesting and I don't know exactly where the problem is. I think it is an extreme condition. Instead of the main component on the whole page I want to render the preloader on the whole page
class Items extends Component {
render () {
return (
<div className="container">
{this.state.items && this.state.items.length ?
<div className="items">
<div className="item">
<span>
<i></i>
</span>
<h4></h4>
<div className="select">
<button></button>
</div>
</div>
<div className="section">
<input/>
<span>
<i></i>
</span>
</div>
<div>
'AAAAAAA'
</div>
<div className="scroll">
{this.state.items.length === 0 && this.state.status === 1 ?
<div className="array">
<p>AAAAAA</p>
</div>
:
this.state.items && this.state.items.length ?
this.state.items.map((todo, index) =>
<Item
key={item.id}
index={index}
/>
)
:
<div className="preloader">
</div>
}
</div>
</div>
<div className="another">
<Component1
/>
<Component2
/>
</div>
:
<Preloader />
</div>
)
}
}
You were missing an } before the last div to close the first ternary and you were missing a wrapping tag for the first ternaries first expression (I used a React.Fragment). Code snippet bellow should be syntactically correct. I do recommend you refactor your code though.
class Items extends Component {
render() {
return (
<div className="container">
{this.state.items && this.state.items.length ? (
<React.Fragment>
<div className="items">
<div className="item">
<span>
<i></i>
</span>
<h4></h4>
<div className="select">
<button></button>
</div>
</div>
<div className="section">
<input />
<span>
<i></i>
</span>
</div>
<div>'AAAAAAA'</div>
<div className="scroll">
{this.state.items.length === 0 && this.state.status === 1 ? (
<div className="array">
<p>AAAAAA</p>
</div>
) : this.state.items && this.state.items.length ? (
this.state.items.map((todo, index) => (
<Item key={item.id} index={index} />
))
) : (
<div className="preloader"></div>
)}
</div>
</div>
<div className="another">
<Component1 />
<Component2 />
</div>
</React.Fragment>
) : (
<Preloader />
)}
</div>
);
}
}

How to pass dynamic value to div element and then access it - React ?

I'm mapping all of my files
_renderItems = files =>
files
? files.map((item, i) => {
return <ProjectItemUser {...item} key={i} index={i} />;
})
: null;
and then I'm trying to display it ProjectItemUser
class ProjectItemUser extends Component {
render() {
return (
<div>
<div className="book_item">
<div className="book_header">
<h2>{this.props.name}</h2>
</div>
<div className="book_this">
<div className="book_author">{this.props.subject}</div>
<div className="book_bubble">
<strong>Study: </strong> {this.props.study}
</div>
<div className="book_bubble">
<strong>Grade: </strong> {this.props.grade}
</div>
<FontAwesomeIcon icon="trash" id="trash" />
</div>
</div>
</div>
);
}
}
This basically displays all the files, and each file is its own separate row. I would like to assign value to div element on each iteration, so I can control which file has been clicked.
I can access my id with: this.props._id
Should this be done using refs and if so, how ?
You should pass onClick function as parameter
_renderItems = files =>
files
? files.map((item, i) => {
return <ProjectItemUser {...item} key={i} index={i} onClick={() => { console.warn(item) } />;
})
: null;
class ProjectItemUser extends Component {
render() {
return (
<div>
<div className="book_item">
<div className="book_header">
<h2>{this.props.name}</h2>
</div>
<div className="book_this">
<div className="book_author">{this.props.subject}</div>
<div className="book_bubble">
<strong>Study: </strong> {this.props.study}
</div>
<div className="book_bubble">
<strong>Grade: </strong> {this.props.grade}
</div>
<FontAwesomeIcon icon="trash" id="trash" />
<Button onClick={this.props.onClick} label="Click on me" />
</div>
</div>
</div>
);
}
}

Categories