I have two page: Header.js and Post.js. These pages is joined on main page - Home.js. Post.js has button "Buy". This button creates variable with value 0 or 1. This value is saved on local storage with window.localStorage.setItem(). And I Want to take with value and give to Header.js. But when I do this value isn't updated avere time, when I click "buy"
How can I make this?
window.localStorage.setItem('countcart',count);
const sumCount = async () => {
if(count === 0){
setCount(Math.max(count 1,0));
} else{
setCount(Math.max(count-1,0));
}
};
<Button className={styles.buy} onClick={sumCount} variant="contained" endIcon={<ShoppingCartIcon fontSize="small"/>}><div className={styles.buytext}>Buy</div> </Button>
CodePudding user response:
If you want localStorage to update every time count
is changed, you should wrap it with a useEffect
:
useEffect(() => {
window.localStorage.setItem('countcart',count);
}, [count])
But, this doesn't auto-update the count value in the other component; to do that with localStorage you'd need to use the https://developer.mozilla.org/en-US/docs/Web/API/Window/storage_event
But, a better way for the other component to access count
would be to declare count
as a state in the parent component and pass its state to the Header.js
and Post.js
components, e.g.:
// App.js
function App() {
const [count, setCount] = useCount(window.localStorage.getItem('count'));
useEffect(() => {
window.localStorage.setItem('countcart',count);
}, [count])
return (
<>
<Header count={count} setCount={setCount} />
<Post count={count} setCount={setCount} />
</>
)
}
CodePudding user response:
import {Routes, Route} from 'react-router-dom';
import Container from '@mui/material/Container';
import { Header } from './components';
import { Home, FullPost, Registration, AddPost, Login, PostsByTag, Account } from './pages';
import { useDispatch, useSelector } from 'react-redux';
import React, { useState } from 'react';
import { fetchAuthMe, selectIsAuth } from './redux/slices/auth';
function App() {
const dispatch = useDispatch();
const [count, setCount] = useState(window.localStorage.getItem('countcart')? 0 :window.localStorage.getItem('countcart'));
const isAuth = useSelector(selectIsAuth);
React.useEffect(()=>{
dispatch(fetchAuthMe());
window.localStorage.setItem('countcart',count);
},[count])
return (
<>
<Header count={count} setCount={setCount}/>
<Container maxWidth="lg">
<Routes>
<Route path="/" element={<Home count={count} setCount={setCount}/>} />
<Route path="/posts/:id" element={<FullPost />} />
<Route path="/tags/:tag" element={<PostsByTag />} />
<Route path="/posts/:id/edit" element={<AddPost />} />
<Route path="/add-post" element={<AddPost />} />
<Route path="/login" element={<Login />} />
<Route path="/register" element={<Registration />} />
<Route path="/account/:id" element={<Account />} />
</Routes>
</Container>
</>
);
}
export default App;
import React from 'react';
import { Rating,IconButton, Button} from '@mui/material';
import clsx from 'clsx';
import {Link, useNavigate} from 'react-router-dom';
import DeleteIcon from '@mui/icons-material/Clear';
import EditIcon from '@mui/icons-material/Edit';
import EyeIcon from '@mui/icons-material/RemoveRedEyeOutlined';
import CommentIcon from '@mui/icons-material/ChatBubbleOutlineOutlined';
import ShoppingCartIcon from '@mui/icons-material/ShoppingCart';
import styles from './Post.module.scss';
// import { UserInfo } from '../UserInfo';
import { PostSkeleton } from './Skeleton';
import { useDispatch } from 'react-redux';
import { fetchRemovePost } from '../../redux/slices/posts';
export const Post = ({
id,
title,
createdAt,
imageUrl,
user,
viewsCount,
commentsCount,
tags,
children,
isFullPost,
isLoading,
isEditable,
count,
setCount,
}) => {
// const [count, setCount] = React.useState(0);
const dispatch = useDispatch();
const navigate = useNavigate();
if (isLoading) {
return <PostSkeleton />;
}
console.log(count);
window.localStorage.setItem('countcart',count);
const sumCount = async () => {
if(count === 0){
setCount(Math.max(count 1,0));
} else{
setCount(Math.max(count-1,0));
}
};
const onClickRemove = () => {
if(window.confirm('Do you sure want to remove post?')){
dispatch(fetchRemovePost(id));
navigate(0);
}
};
return (
<div className={clsx(styles.root, { [styles.rootFull]: isFullPost })}>
{isEditable && (
<div className={styles.editButtons}>
<Link to={`/posts/${id}/edit`}>
<IconButton color="primary">
<EditIcon />
</IconButton>
</Link>
<IconButton onClick={onClickRemove} color="secondary">
<DeleteIcon />
</IconButton>
</div>
)}
{imageUrl && (
<img
className={clsx(styles.image, { [styles.imageFull]: isFullPost })}
src={imageUrl}
alt={title}
/>
)}
<div className={styles.wrapper}>
<div className={styles.indention}>
<h2 className={clsx(styles.title, { [styles.titleFull]: isFullPost })}>
{isFullPost ? title : <Link to={`/posts/${id}`}>{title}</Link>}
</h2>
<div className={styles.ratingprice}>
<Rating
name="size-small"
value={2.5}
size="small"
precision={0.5}
readOnly
/>
<div className={styles.review}>12 отзывов</div>
</div>
<div className={styles.price}>1150 руб.</div>
{children && <div className={styles.content}>{children}</div>}
<div className={styles.postDetails}>
<ul className={styles.postDetails}>
<li>
<EyeIcon />
<span>{viewsCount}</span>
</li>
<li>
<CommentIcon />
<span>{commentsCount}</span>
</li>
</ul>
<Button className={styles.buy} onClick={sumCount} variant="contained" endIcon={<ShoppingCartIcon fontSize="small"/>}><div className={styles.buytext}>Купить</div> </Button>
</div>
</div>
</div>
</div>
);
};