React onClick not responding - javascript

I am a newbie in react. I am not so sure why this onClick event is not responding. I am trying render a modal when icon is clicked for some reasons I am the onClick event is not responding. I have tried it in 2 ways
onClick = {()=> {handleEdit()}
onClick = {handleEdit}
I am using this NoteWidget in another component called customerProfile is I dont know if that is creating any issue.
import React from 'react'
import './Notewidget.scss'
import AddCircleIcon from '#mui/icons-material/AddCircle';
import {List, Skeleton,Divider,Modal,Input} from 'antd';
import InfinteScroll from 'react-infinite-scroll-component';
import {useState} from 'react';
const Notewidget = () => {
const [isEditing,setIsEditing] = useState(false);
const handleEdit = () => {
console.log('button clicked');
setIsEditing(true);
}
return (
<div className='notes'>
<div className='heading'>
<h3 className='title'>NOTES</h3>
<div className='icon'><AddCircleIcon onClick={() => {handleEdit()}}/></div>
</div>
<div className='list'
style={{
overflow:'auto',
padding:'0px px',
width:400,
height:543
}}
>
<InfinteScroll
dataLength={data.length}
next={data}
size='large'
hasMore={data.length < 5}
loader={
<Skeleton
avatar
paragraph={{
rows:1,
}}
active
/>
}
endMessage={<Divider plain>Add Note</Divider>}>
<List
itemLayout="horizontal"
dataSource={data}
renderItem={(item)=>(
<List.Item>
<List.Item.Meta
title={item.title}
description={item.description}
/>
</List.Item>
)}
/>
</InfinteScroll>
</div>
<Modal
visible={isEditing}>
</Modal>
</div>
)
}
export default Notewidget
when I am clicking on the border next to notes it is working the modal is popping up
#import "antd/dist/antd.css";
.notes{
flex:1;
margin-right: 20px;
gap: 20px;
padding: 10px;
justify-content: space-between;
height: 650px;
-webkit-box-shadow: 2px 4px 10px 1px rgba(0,0,0,0.47);
box-shadow: 2px 4px 10px 1px rgba(201,201,201,0.47);
background-color: white;
.heading{
display: flex;
justify-content: space-between;
h3{
padding: 20px;
.title{
font-size: 14px;
font-weight:bolder;
line-height: 1.2;
text-transform: uppercase;
color: rgb(50, 51, 50);
margin: 0px 0px 20px;
}
}
.icon{
padding-top: 16px;
padding-left: 265px;
}
}
.list{
padding: 10px;
}
}

There are couple of things -
did you check the console log in developer mode?
Yes, the way you have told to invoke the functions are connect but there is more to it. for time-being if you are not passing any parameters to function then you should use the 2nd way [ onClick = {handleEdit}]
3.since you have attached your handler to mui Icon, that might be the reason. try putting the onClick to parent of icon i.e div like this -
<div className='icon' onClick={handleEdit}><AddCircleIcon/></div>
4.please try put some playground link (JS fiddle/codeSandbox) so that anyone can try doing changes in code.

Related

How can I return state separately when I use redux and array?

I'm trying to implement like function by using redux and map function to use states in other components. I used redux not using useState([]) because I thought it is better way to manage states. I made the button changed when button is clicked. But they are sharing same state so it is changed at the same time. To solve this problem, I think I should add this state in array. And here comes my question. How can I add state declared in redux to manage state separately? And is this way correct? I'll upload concrete code including redux by using codesandbox. I'd appreciate it if you let me know, thanks.
Clothes
import React, { useState } from "react";
import styled from "styled-components";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import { faHeart } from "#fortawesome/free-solid-svg-icons";
import { faHome } from "#fortawesome/free-solid-svg-icons";
import { useDispatch, useSelector } from "react-redux";
const array = [
{
id: "1",
name: "vest",
img:
"https://shopimg.kakaofriendsgolf.com/live/images/2022/9/7/10/918997_1662515279620.png",
price: "10000"
},
{
id: "2",
name: "shirts",
img:
"https://shopimg.kakaofriendsgolf.com/live/images/2022/8/23/18/551886_1661246483199.png",
price: "12000"
},
{
id: "3",
name: "pants",
img:
" https://shopimg.kakaofriendsgolf.com/live/images/2022/8/22/18/18783_1661159105201.png",
price: "15000"
}
];
export default function Clothes() {
const isClick = useSelector((state) => state.CheckLike.isClick);
const dispatch = useDispatch();
// change Icon
const setHide = (e) => {
dispatch({ type: "False" });
};
const setShow = (e) => {
dispatch({ type: "True" });
};
return (
<Wrap>
<div className="productCard">
{array.map((content, idx) => {
return (
<div key={idx} className="productCard__wrap">
<img src={content.img} className="productCard__img" />
<div className="productCard__name">
<div>
<h3 className="productCard__title">{content.name}</h3>
<div className="productCard__priceWrap">
{content.price
.toString()
.replace(/\B(?=(\d{3})+(?!\d))/g, ",")}
</div>
</div>
<div className="productCard__likeWrap">
{/* show heart and house icon according to state */}
{isClick ? (
<div
onClick={() => {
setHide();
}}
>
<FontAwesomeIcon icon={faHeart} />
</div>
) : (
<div
onClick={() => {
setShow();
}}
>
<FontAwesomeIcon icon={faHome} />
</div>
)}
</div>
</div>
</div>
);
})}
</div>
</Wrap>
);
}
const Wrap = styled.div`
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
overflow: scroll;
.productCard {
display: flex;
position: absolute;
top: calc(50vh - 120px);
left: calc(50vw - 180px);
width: "228px";
height: "351px";
padding-right: 8px;
padding-left: 8px;
border: solid 1px black;
}
.productCard__wrap {
border: 1px solid grey;
line-height: 1.428571429;
background-color: #fff;
}
.productCard__img {
width: 228px;
height: 228px;
}
.productCard__name {
padding-bottom: 30px;
position: relative;
padding: 8px 8px 0 8px;
min-height: 118px;
text-align: left;
}
.productCard__title {
font-size: 18px;
margin-top: 0;
margin-bottom: 2px;
padding-right: 37px;
line-height: 1.3;
margin-block-start: 1em;
margin-block-end: 1em;
}
.productCard__priceWrap {
font-size: 18px;
margin-top: 5px;
vertical-align: middle;
margin: 0 0 9px;
margin-block-start: 1em;
margin-block-end: 1em;
text-align: left;
}
.productCard__likeWrap {
position: absolute;
top: -5px;
right: 0;
padding: 0;
height: 40px;
line-height: 37px;
white-space: normal;
display: inline-block;
margin-bottom: 0;
font-weight: normal;
text-align: center;
}
`;
codesandbox
https://codesandbox.io/s/likepractice-tpcv7l?file=/src/components/Clothes.jsx
There could be many approaches, but assuming that the goal is to make the like button work for individual items and save the liked items in the store, I think the solution of using an array as a state is suitable in the use case.
Forked demo with modification: codesandbox
Configure the state as an array and create matching reducers, here the product id is saved to the state array when liked, but this is an optional approach.
const initailState = {
isClick: [],
};
const CheckLike = (state = initailState, action) => {
switch (action.type) {
case "True":
return {
...state,
isClick: [...state.isClick, action.id],
};
case "False":
return {
...state,
isClick: state.isClick.filter((id) => id !== action.id),
};
default:
return {
...state,
};
}
};
Edit the event handler to dispatch the item id to be added or removed from the state array:
const setHide = (id) => {
dispatch({ type: "False", id });
};
const setShow = (id) => {
dispatch({ type: "True", id });
};
Check if product id content.id is included in the state array as a condition for rendering the icons, and wire up the icons to send content.id to the events:
<div className="productCard__likeWrap">
{isClick.includes(content.id) ? (
<div
onClick={() => {
setHide(content.id);
}}
>
<FontAwesomeIcon icon={faHeart} />
</div>
) : (
<div
onClick={() => {
setShow(content.id);
}}
>
<FontAwesomeIcon icon={faHome} />
</div>
)}
</div>
if I'm guessing correctly your problem is that the button click changes all the buttons.
for this issue, you don't need redux. use redux when you want to manage a global state used in multiple components(ex, session).
solution for your problem is, create a new component for each product card and there manage the state of the button.
and to store which products are on the wishlist you can store that in redux.

select list returns previous value after closing and reopening

I have a list and I choose a value from the list.
For example "Mercedes".
But I close this list with the "Save" or "Close" button and when I open it again, "Mercedes" is selected. How can I prevent this?
<Modal isOpen={app.showCars} >
<ModalHeader>
</ModalHeader>
<ModalBody>
<Select
options={carList}
onChange={(car) => (app.addcar = car)}
value={app.addcar }
/>
</ModalBody>
<ModalFooter>
<Button onClick={() => {
app.addcar()
app.showCarModal = false;
}}>Save</Button>
<Button onClick={() => {
app.showCarModal = false;
}}> Close </Button>
</ModalFooter>
</Modal>
(I borrowed this code from one of my other answers because it was easier to change that than try to work out what UI library you're using. You can ignore most of it - the important part is in the Example component at the bottom.)
Going back to my comment:
Maintain the state of the last selected option, and then use that state to declare the default selected option when the select is rendered again.
The parent component (Example) should manage the state of both the modal (open or closed), and the current selection. So we initialise a new state called selected that can be updated using the corresponding setSelected function.
We pass that state, and a handler down to the Select component. We use the selected property to set the default option on the select (I imagine your UI library Select component allows this too), and call the handleChange handler whenever a new option is chosen. The handler updates the state so whenever the modal opens again that option will be pre-selected.
const { useState } = React;
// Create the modal component which accepts two handlers,
// and "children" which is the HTML you want to show
function Modal({ isOpen, onClose, children }) {
if (!isOpen) return null;
return ReactDOM.createPortal(
<div className="modal">
{children}
<button
className="closemodal"
onClick={onClose}
>Close
</button>
</div>,
document.body
);
}
// Pass in the handler to the Nav component
function Nav({ handleModal }) {
return (
<nav>
<a onClick={handleModal}>Open modal</a>
</nav>
);
}
// ContactUs builds the form within the modal
// We pass in the showModal state, and the handler
function Select(props) {
const {
selected,
handleSelected
} = props;
return (
<select defaultValue={selected} onChange={handleSelected}>
<option selected disabled value="default">Select something</option>
<option value="bob">Bob</option>
<option value="sara">Sara</option>
<option value="kevin">Kevin</option>
<option value="teresa">Teresa</option>
</select>
);
}
function Example() {
const [ selected, setSelected ] = useState('default');
const [ showModal, setShowModal ] = useState(false);
// Our main handler for the modal. It simply
// toggles between true and false
function handleModal() {
setShowModal(!showModal);
}
// Sets a new state with the selected option value
function handleSelected(e) {
setSelected(e.target.selectedOptions[0].value);
}
return (
<div>
<Nav handleModal={handleModal} />
<Modal isOpen={showModal} onClose={handleModal}>
<Select
selected={selected}
handleSelected={handleSelected}
/>
</Modal>
</div>
);
};
ReactDOM.render(
<Example />,
document.getElementById('react')
);
nav { padding: 1em; margin: 0.2em; background-color: #efefef; }
nav a { border: 2px solid #454545; padding: 0.25em; }
nav a:hover { cursor: pointer; background-color: #dfdfdf; }
.modal { position: fixed; inset: 0; background-color: white; margin: 0.5em; border: 2px solid #343434; display: flex; flex-direction: column; align-items: center; justify-content: center; overflow: hidden; overflow-y:scroll; transition: all 0.3s ease-in-out; z-index: 999; }
fieldset { margin-bottom: 1em; background-color: #efefef; }
.closemodal { padding: 0.5em; background-color: #336699; color: white; }
.send { background-color: #44aa77; color: white; }
.closemodal:hover, .send:hover { cursor: pointer; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>

styles applied to Horizontal Line via css file is not working

https://codesandbox.io/s/goofy-pasteur-ntcuj
import "./styles.css";
export default function App() {
const separator = {
backgroundColor: "#E9E9E9",
height: "12px",
margin: "8px",
borderRadius: "4px"
};
return (
<div className="App">
<hr style={separator} />
<hr className="line-separator" />
</div>
);
}
.line-separator {
background-color: #e9e9e9;
height: 2px;
margin: 8px;
border-radius: 4px;
}
styles applied via java script is working fine but the same is not working from css for <hr /> tag.
Your className is wrong.
try: <hr className="line-separator" />
You have another Typo in your CSS, your height should be 12px not 2px
you have a typo in setting className of the second hr as "separator". It should match the className specified in the css file.
Correct code:
import "./styles.css";
export default function App() {
const separator = {
backgroundColor: "#E9E9E9",
height: "12px",
margin: "8px",
borderRadius: "4px"
};
return (
<div className="App">
<hr style={separator} />
<hr className="line-separator" />
</div>
);
}
.line-separator {
background-color: #e9e9e9;
height: 2px;
margin: 8px;
border-radius: 4px;
}
this should be a super quick fix:
Your className needs to match the name of the css class .line-separator
import "./styles.css";
export default function App() {
const separator = {
backgroundColor: "#E9E9E9",
height: "12px",
margin: "8px",
borderRadius: "4px"
};
return (
<div className="App">
<hr style={separator} />
<hr className="line-separator" />
</div>
);
}
The height value here just needs changing to 12px
.line-separator {
background-color: #e9e9e9;
height: 12px;
margin: 8px;
border-radius: 4px;
}

onDoubleClick is not working on react to call a function

I'm following this React tutorial here: https://ibaslogic.com/how-to-edit-todos-items-in-react/ to build a simple TO DO app.
I've also reviewed Why onDoubleClick event is not working in React.js? but there's no onclick event to worry about in my example.
My onDoubleClick event should call a function handleEditing but nothing happens when I double click a list item.
I'm unsure of why it does not work (the web browser does not seem to register a double click event.
Below is my example:
import React from "react";
import styles from "./TodoItem.module.css";
class TodoItem extends React.Component {
state = {
editing: false,
};
handleEditing = () => {
console.log("doubleClick")
this.setState({
editing: true,
});
};
render() {
const completedStyle = {
fontStyle: "italic",
color: "#595959",
opacity: 0.4,
textDecoration: "line-through",
};
const { completed, id, title } = this.props.todo;
let viewMode = {}
let editMode = {}
if (this.state.editing) {
viewMode.display = "none"
} else {
editMode.display = "none"
}
return (
<li className={styles.item}>
<div onDoubleClick={this.handleEditing} style={viewMode}>
<input
type="checkbox"
className={styles.checkbox}
checked={completed}
onChange={() => this.props.handleChangeProps(id)}
/>
<button onClick={() => this.props.deleteTodoProps(id)}>Delete</button>
<span style={completed ? completedStyle : null}>{title}</span>
</div>
<input type="text" style={editMode} className={styles.textInput} />
</li>
);
}
}
export default TodoItem;
I don't think this is relevant, but here is my css:
.item {
font-size: 1.2rem;
list-style-type: none;
padding: 17px 0px;
border-bottom: 1px solid #eaeaea;
}
.checkbox {
margin-right: 15px;
}
.item button {
font-size: 13px;
background: #f1f3f4;
border: none;
cursor: pointer;
float: right;
outline: none;
border-radius: 100px;
height: 50px;
width: 50px;
margin: -10px 0 0 10px;
}
.textInput {
width: 100%;
padding: 10px;
border: 1px solid #dfdfdf;
}
onDoubleClick works when your dev tool is not opened
Updated answer:
As found out in the comments, the problem was a combination of OS and Browser. Windows / Chrome in this example.
Old answer:
I haven't read into much detail, but the first difference I can spot is that in your code the handleEditing is not bound. Which should not prevent the output of your console.log. Does it appear?
onDoubleClick={this.handleEditing.bind(this)}
Hope this helps in your case.

Scroll is skipping header and starting from body

When site is loading, page starts from body and I have to scroll up to see styled header.
(But this problem does not appear on all browsers)
I want to start scrolling with the Header.
Here is the live site: http://pavlorishko228-001-site1.btempurl.com/
Code:
import React from "react";
import { Link } from 'react-router-dom';
import styled from "styled-components";
import ScrollHandler from "../../components/ScrollHandler";
import Logo from '../../public/SmokeyWayLogo.svg';
const StyledLogo = styled("img")<{isScrolled: boolean}>`
filter: ${props => props.isScrolled ? "invert(1)" : "drop-shadow(2px 4px 3px black)"};
height: 80px;
padding-left: 0;
float: left;
`;
const StyledLink = styled("div")<{isScrolled: boolean}>`
padding: 20px;
margin: 10px;
display: inline-block;
border-radius: 5px;
&:hover {
box-shadow: 0px 0px 15px 2px ${props => props.isScrolled ? "white" : "black"};
color: black;
}
a {
text-decoration: inherit;
color: ${props => props.isScrolled ? "white" : "black"};
}
`;
const StyledNav = styled("div")<{isScrolled: boolean}>`
position: fixed;
width: 100%;
background-color: ${props => props.isScrolled ? "transparent " : "white"};
`;
function Header(){
const _isScrolled = ScrollHandler();
return(
<header>
<StyledNav isScrolled={_isScrolled}>
<StyledLogo isScrolled={_isScrolled} src={Logo}></StyledLogo>
<StyledLink isScrolled={_isScrolled}>
<Link to="./">Smokey Way</Link>
</StyledLink>
<StyledLink isScrolled={_isScrolled}>
<Link to="./">Головна</Link>
</StyledLink>
<StyledLink isScrolled={_isScrolled}>
<Link to="./">Меню</Link>
</StyledLink>
</StyledNav>
</header>
)
}
export default Header;
I used chrome on my device and was fine, I mean i saw your header after loading the page.
Your problem is not normal and its kinda weird for me, But i suggest you JS (in this code before loading page it makes you to be sure that you are at the top of the current page) and give me the feedback:
$(window).on('beforeunload', function(){
$(window).scrollTop(0);
});

Categories