useSelector rendering infinitely - reactjs

When trying to set value equal to state value using useSelector value is reassigned again and again.
code below console logs quantities infintely
const quantities = useSelector((state) => state.cart.quantity) console.log(quantities)
Cart slice:
import { createSlice } from '#reduxjs/toolkit'
const cartSlice = createSlice({
name: 'cart',
initialState: {
products: [],
quantity: 0,
total: 0,
},
reducers: {
addProduct: (state, action) => {
state.quantity += 1
state.products.push(action.payload)
state.total += action.payload.price * action.payload.quantity
},
},
})
export const { addProduct } = cartSlice.actions
export default cartSlice.reducer
Store.js
import { configureStore, combineReducers } from '#reduxjs/toolkit'
import cartReducer from './cartRedux'
import userReducer from './userRedux'
import {
persistStore,
persistReducer,
FLUSH,
REHYDRATE,
PAUSE,
PERSIST,
PURGE,
REGISTER,
} from 'redux-persist'
import storage from 'redux-persist/lib/storage'
const persistConfig = {
key: 'root',
version: 1,
storage,
}
const rootReducer = combineReducers({ user: userReducer, cart: cartReducer })
const persistedReducer = persistReducer(persistConfig, rootReducer)
export const store = configureStore({
reducer: persistedReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: {
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
},
}),
})
export let persistor = persistStore(store)
entire component
import { Search, ShoppingCartOutlined } from '#material-ui/icons'
import React from 'react'
import styled from 'styled-components'
import { mobile } from '../responsive'
import { useSelector } from 'react-redux'
import { Link } from 'react-router-dom'
import _ from 'underscore'
const Container = styled.div`
height: 60px;
${mobile({ height: '50px' })}
`
const Wrapper = styled.div`
padding: 10px 20px;
display: flex;
align-items: center;
justify-content: space-between;
${mobile({ padding: '10px 0px' })}
`
const Left = styled.div`
flex: 1;
display: flex;
align-items: center;
`
const Language = styled.span`
font-size: 14px;
cursor: pointer;
${mobile({ display: 'none' })}
`
const SearchContainer = styled.div`
border: 0.5px solid lightgray;
display: flex;
align-items: center;
margin-left: 25px;
padding: 5px;
`
const Input = styled.input`
border: none;
${mobile({ width: '50px' })}
`
const Center = styled.div`
flex: 1;
text-align: center;
`
const Logo = styled.h1`
font-weight: bold;
${mobile({ fontSize: '24px' })}
`
const Right = styled.div`
flex: 1;
display: flex;
align-items: center;
justify-content: flex-end;
${mobile({ flex: 2, justifyContent: 'center' })}
`
const MenuItem = styled.div`
font-size: 14px;
cursor: pointer;
margin-left: 25px;
${mobile({ fontSize: '12px', marginLeft: '10px' })}
`
const Navbar = () => {
const quantities = useSelector((state) => state.cart.quantity)
console.log(quantities)
return (
<Container>
<Wrapper>
<Left>
<Language>EN</Language>
<SearchContainer>
<Input placeholder='Search' />
<Search style={{ color: 'gray', fontSize: 16 }} />
</SearchContainer>
</Left>
<Center>
<Logo>LAMA.</Logo>
</Center>
<Right>
<MenuItem>REGISTER</MenuItem>
<MenuItem>SIGN IN</MenuItem>
<Link to='/cart'>
<MenuItem>
<Badge badgeContent={quantities} color='primary'>
<ShoppingCartOutlined />
</Badge>
</MenuItem>
</Link>
</Right>
</Wrapper>
</Container>
)
}
export default Navbar
Ancestor component
import styled from 'styled-components'
import Announcement from '../components/Announcement'
import Footer from '../components/Footer'
import Navbar from '../components/Navbar'
import Newsletter from '../components/Newsletter'
import { mobile } from '../responsive'
import { useState } from 'react'
import { useEffect } from 'react'
import { publicRequest } from '../requestMethods'
import { Link, useLocation } from 'react-router-dom'
const Container = styled.div``
const Wrapper = styled.div`
padding: 50px;
display: flex;
${mobile({ padding: '10px', flexDirection: 'column' })}
`
const ImgContainer = styled.div`
flex: 1;
`
const Image = styled.img`
width: 100%;
height: 90vh;
object-fit: cover;
${mobile({ height: '40vh' })}
`
const InfoContainer = styled.div`
flex: 1;
padding: 0px 50px;
${mobile({ padding: '10px' })}
`
const Title = styled.h1`
font-weight: 200;
`
const Desc = styled.p`
margin: 20px 0px;
`
const Price = styled.span`
font-weight: 100;
font-size: 40px;
`
const FilterContainer = styled.div`
width: 50%;
margin: 30px 0px;
display: flex;
justify-content: space-between;
${mobile({ width: '100%' })}
`
const Filter = styled.div`
display: flex;
align-items: center;
`
const FilterTitle = styled.span`
font-size: 20px;
font-weight: 200;
`
const FilterColor = styled.div`
width: 20px;
height: 20px;
border-radius: 50%;
background-color: ${(props) => props.color};
margin: 0px 5px;
cursor: pointer;
`
const FilterSize = styled.select`
margin-left: 10px;
padding: 5px;
`
const FilterSizeOption = styled.option``
const AddContainer = styled.div`
width: 50%;
display: flex;
align-items: center;
justify-content: space-between;
${mobile({ width: '100%' })}
`
const AmountContainer = styled.div`
display: flex;
align-items: center;
font-weight: 700;
`
const Amount = styled.span`
width: 30px;
height: 30px;
border-radius: 10px;
border: 1px solid teal;
display: flex;
align-items: center;
justify-content: center;
margin: 0px 5px;
`
const Button = styled.button`
padding: 15px;
border: 2px solid teal;
background-color: white;
cursor: pointer;
font-weight: 500;
&:hover {
background-color: #f8f4f4;
}
`
const Product = () => {
const location = useLocation()
const id = location.pathname.split('/')[2]
const [product, setProduct] = useState({})
const [quantity, setQuantity] = useState(1)
const [color, setColor] = useState('')
const [size, setSize] = useState('')
useEffect(() => {
const getProduct = async () => {
try {
const res = await publicRequest.get('/product/find/' + id)
setProduct(res.data)
} catch {}
}
getProduct()
})
const handleQuantity = (type) => {
if (type === 'dec') {
quantity > 1 && setQuantity(quantity - 1)
} else {
setQuantity(quantity + 1)
}
}
const handleClick = () => {
//update cart
}
return (
<Container>
<Navbar />
<Announcement />
<Wrapper>
<ImgContainer>
<Image src={product.img} />
</ImgContainer>
<InfoContainer>
<Title>{product.title}</Title>
<Desc>{product.desc}</Desc>
<Price>{product.Price}</Price>
<FilterContainer>
<Filter>
<FilterTitle>Color</FilterTitle>
{product.color?.map((c) => (
<FilterColor
color={c}
key={c}
onClick={() => {
setColor(c)
}}
/>
))}
</Filter>
<Filter>
<FilterTitle>Size</FilterTitle>
<FilterSize>
{product.size?.map((s) => (
<FilterSizeOption
key={s}
onChange={(e) => {
setSize(e.target.value)
}}
>
{s}
</FilterSizeOption>
))}
</FilterSize>
</Filter>
</FilterContainer>
<AddContainer>
<AmountContainer>
<Remove onClick={() => handleQuantity('dec')} />
<Amount>{quantity}</Amount>
<Add onClick={() => handleQuantity('inc')} />
</AmountContainer>
<Button onClick={handleClick}>ADD TO CART</Button>
</AddContainer>
</InfoContainer>
</Wrapper>
<Newsletter />
<Footer />
</Container>
)
}
export default Product
I am currently following an online tutorialenter code here but when he writes the same code it console.logs only once.
I even tried copy pasting his code still my code returns logs infinitely.
I just copied the ancestor component from the tutorial video github and it solved the problem but I don't know what was actually causing it if anyone can help
correct ancestor component
import styled from 'styled-components'
import Announcement from '../components/Announcement'
import Footer from '../components/Footer'
import Navbar from '../components/Navbar'
import Newsletter from '../components/Newsletter'
import { mobile } from '../responsive'
import { useLocation } from 'react-router-dom'
import { useEffect, useState } from 'react'
import { publicRequest } from '../requestMethods'
import { addProduct } from '../redux/cartRedux'
import { useDispatch } from 'react-redux'
const Container = styled.div``
const Wrapper = styled.div`
padding: 50px;
display: flex;
${mobile({ padding: '10px', flexDirection: 'column' })}
`
const ImgContainer = styled.div`
flex: 1;
`
const Image = styled.img`
width: 100%;
height: 90vh;
object-fit: cover;
${mobile({ height: '40vh' })}
`
const InfoContainer = styled.div`
flex: 1;
padding: 0px 50px;
${mobile({ padding: '10px' })}
`
const Title = styled.h1`
font-weight: 200;
`
const Desc = styled.p`
margin: 20px 0px;
`
const Price = styled.span`
font-weight: 100;
font-size: 40px;
`
const FilterContainer = styled.div`
width: 50%;
margin: 30px 0px;
display: flex;
justify-content: space-between;
${mobile({ width: '100%' })}
`
const Filter = styled.div`
display: flex;
align-items: center;
`
const FilterTitle = styled.span`
font-size: 20px;
font-weight: 200;
`
const FilterColor = styled.div`
width: 20px;
height: 20px;
border-radius: 50%;
background-color: ${(props) => props.color};
margin: 0px 5px;
cursor: pointer;
`
const FilterSize = styled.select`
margin-left: 10px;
padding: 5px;
`
const FilterSizeOption = styled.option``
const AddContainer = styled.div`
width: 50%;
display: flex;
align-items: center;
justify-content: space-between;
${mobile({ width: '100%' })}
`
const AmountContainer = styled.div`
display: flex;
align-items: center;
font-weight: 700;
`
const Amount = styled.span`
width: 30px;
height: 30px;
border-radius: 10px;
border: 1px solid teal;
display: flex;
align-items: center;
justify-content: center;
margin: 0px 5px;
`
const Button = styled.button`
padding: 15px;
border: 2px solid teal;
background-color: white;
cursor: pointer;
font-weight: 500;
&:hover {
background-color: #f8f4f4;
}
`
const Product = () => {
const location = useLocation()
const id = location.pathname.split('/')[2]
const [product, setProduct] = useState({})
const [quantity, setQuantity] = useState(1)
const [color, setColor] = useState('')
const [size, setSize] = useState('')
const dispatch = useDispatch()
useEffect(() => {
const getProduct = async () => {
try {
const res = await publicRequest.get('/product/find/' + id)
setProduct(res.data)
} catch {}
}
getProduct()
}, [id])
const handleQuantity = (type) => {
if (type === 'dec') {
quantity > 1 && setQuantity(quantity - 1)
} else {
setQuantity(quantity + 1)
}
}
const handleClick = () => {
dispatch(addProduct({ ...product, quantity, color, size }))
}
return (
<Container>
<Navbar />
<Announcement />
<Wrapper>
<ImgContainer>
<Image src={product.img} />
</ImgContainer>
<InfoContainer>
<Title>{product.title}</Title>
<Desc>{product.desc}</Desc>
<Price>$ {product.price}</Price>
<FilterContainer>
<Filter>
<FilterTitle>Color</FilterTitle>
{product.color?.map((c) => (
<FilterColor color={c} key={c} onClick={() => setColor(c)} />
))}
</Filter>
<Filter>
<FilterTitle>Size</FilterTitle>
<FilterSize onChange={(e) => setSize(e.target.value)}>
{product.size?.map((s) => (
<FilterSizeOption key={s}>{s}</FilterSizeOption>
))}
</FilterSize>
</Filter>
</FilterContainer>
<AddContainer>
<AmountContainer>
<Remove onClick={() => handleQuantity('dec')} />
<Amount>{quantity}</Amount>
<Add onClick={() => handleQuantity('inc')} />
</AmountContainer>
<Button onClick={handleClick}>ADD TO CART</Button>
</AddContainer>
</InfoContainer>
</Wrapper>
<Newsletter />
<Footer />
</Container>
)
}
export default Product

Related

react transition effect not work after async thunk

Although I have updated the todo status, the checkbox effect is not working correctly, as if no effect has been applied, what could be the reason for this? I don't think there is a problem with the api file, but the api request is taking a long time.I think it's because css doesn't render again, I can't think of anything else..
Thank you for helping
import React from "react";
import { useDispatch } from "react-redux";
import { toggleTodos } from "../redux/slice/thunkActions";
import styled from "styled-components";
const Content = styled.div`
color: #fff;
text-transform: capitalize;
`;
const Options = styled.div`
display: flex;
align-items: center;
justify-content: center;
gap: 2rem;
`;
const EditButton = styled.button`
cursor: pointer;
background-color: #ff6b81;
padding: 0.7rem 2rem;
color: #fff;
border-radius: 0.5rem;
font-weight: bold;
`;
const InputWrapper = styled.label`
position: relative;
`;
const Input = styled.input`
position: absolute;
left: -99999px;
top: -99999px;
&:checked + span {
background-color: #1890ff;
transition: 1s;
&:before {
left: calc(100% - 0.2rem);
transform: translateX(-100%);
}
}
`;
const Slider = styled.span`
display: flex;
width: 5rem;
height: 2.5rem;
cursor: pointer;
border-radius: 10rem;
background-color: #fcebb6;
transition: background-color 0.4s;
&:before {
content: "";
position: absolute;
top: 0.2rem;
left: 0.2rem;
width: 2.1rem;
height: 2.1rem;
border-radius: 2.1rem;
transition: 1s;
background-color: #fff;
}
`;
const Todo = ({ todo }) => {
const dispatch = useDispatch();
const handleChange = (todo) => {
dispatch(toggleTodos(todo));
};
return (
<li>
<Content>{todo.content}</Content>
<Options>
<EditButton type="button">Edit</EditButton>
<InputWrapper htmlFor={`todoContent${todo.id}`}>
<Input
id={`todoContent${todo.id}`}
type={"checkbox"}
onChange={() => handleChange(todo)}
checked={todo && todo.isCompleted}
/>
<Slider />
</InputWrapper>
</Options>
</li>
);
};
export default Todo;

Uncaught Error: Cannot find module './undefined'

I watched the code multiple times to figure out the problem but couldn't find the solution to this exception thrown at the console. The Product page blanks out.
Product.jsx
import React, { useEffect, useState } from 'react'
import Navbar from '../../Components/Navbar/Navbar'
import Announcment from '../../Components/Announcment/Announcment'
import Newsletter from '../../Components/Newsletter/Newsletter'
import Footer from '../../Components/Footer/Footer'
import styled from 'styled-components'
import './Product.css'
import { Add, Remove } from '#mui/icons-material'
import { useLocation } from 'react-router-dom'
import {publicRequest} from '../../requestMethod';
const Container = styled.div`
`
const Wrapper = styled.div`
padding: 50px;
display: flex;
`
const ImageContainer = styled.div`
flex: 1;
`
const InfoContainer = styled.div`
flex: 1;
padding: 0 50px;
`
const Title = styled.h1`
font-weight: 200;
`
const Desc = styled.p`
margin: 20px 0;
`
const Price = styled.span`
font-weight: 100;
font-size: 40px;
`
const FilterContainer = styled.div`
width: 50%;
display: flex;
justify-content: space-between;
margin: 30px 0;
`
const Filter = styled.div`
display: flex;
align-items: center;
`
const FilterTitle = styled.span`
font-size: 20px;
font-weight: 200;
`
const FilterColor = styled.div`
width: 20px;
height: 20px;
border-radius: 50%;
background-color: ${props => props.color};
margin: 0 5px;
cursor: pointer;
`
const FilterSize = styled.select`
margin-left: 10px;
padding: 5px;
`
const FilterSizeOption = styled.option`
`
const AddContainer = styled.div`
width: 50%;
display: flex;
align-items: center;
justify-content: space-between;
`
const AmountContainer = styled.div`
display: flex;
align-items: center;
font-weight: 700;
`
const Amount = styled.span`
width: 30px;
height: 30px;
border-radius: 10px;
border: 1px solid teal;
display: flex;
justify-content: center;
align-items: center;
margin: 0 5px;
`
const Button = styled.button`
padding: 15px;
border: 3px solid teal;
background-color: white;
cursor: pointer;
font-weight: 500;
&:hover{
background-color: #f8f4f4;
}
`;
const Product = () => {
const location = useLocation();
const Id = location.pathname.split('/')[2];
const [product, setProduct] = useState({});
useEffect(() => {
const getSingleProduct = async () => {
try {
const res = await publicRequest.get(`/products/find/${Id}`);
setProduct(res.data);
} catch (error) {
console.log(error);
}
}
getSingleProduct();
}, [Id]);
return (
<Container>
<Navbar />
<Announcment />
<Wrapper>
<ImageContainer>
<img src={require(`../../Assets/${product.img}`)} alt='' className='productImg2' />
</ImageContainer>
<InfoContainer>
<Title>{product.title}</Title>
<Desc>{product.desc}</Desc>
<Price>$ {product.price}</Price>
<FilterContainer>
<Filter>
<FilterTitle>Color</FilterTitle>
{product.color.map((c, i) => (
<React.Fragment key={i}>
<FilterColor color={c} />
</React.Fragment>
))
}
</Filter>
<Filter>
<FilterTitle>Size</FilterTitle>
<FilterSize>
{product.size.map((s, i) => (
<React.Fragment key={i}>
<FilterSizeOption>{s}</FilterSizeOption>
</React.Fragment>
))
}
</FilterSize>
</Filter>
</FilterContainer>
<AddContainer>
<AmountContainer>
<Remove style={{ cursor: "pointer" }} />
<Amount>1</Amount>
<Add style={{ cursor: "pointer" }} />
</AmountContainer>
<Button>ADD TO CART</Button>
</AddContainer>
</InfoContainer>
</Wrapper>
<Newsletter />
<Footer />
</Container>
);
}
export default Product
requestMethod.js
import axios from 'axios';
const BASE_URL = "http://localhost:5000/api";
const Token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYyZjI5NmRjY2JmYzNjZTAyNGRhODNlNSIsImlzQWRtaW4iOnRydWUsImlhdCI6MTY2MDEzMzExNiwiZXhwIjoxNjYwMzkyMzE2fQ.TMBcTYhOKhsGTqHgVY6fAGoX9UCc2rC100JwvzoSqhE";
export const publicRequest = axios.create({
baseURL:BASE_URL,
});
export const userRequest = axios.create({
baseURL:BASE_URL,
headers:{token:`Bearer ${Token}`},
});
error
.$:106 Uncaught Error: Cannot find module './undefined'
at webpackContextResolve (.$:106:1)
at webpackContext (.*$:101:1)
at Product (Product.jsx:120:1)
at renderWithHooks (react-dom.development.js:16305:1)
at mountIndeterminateComponent (react-dom.development.js:20074:1)
at beginWork (react-dom.development.js:21587:1)
at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1)
at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1)
at invokeGuardedCallback (react-dom.development.js:4277:1)
at beginWork$1 (react-dom.development.js:27451:1)
The above error occurred in the component:
at Product (http://localhost:3000/static/js/bundle.js:3288:81)
at Routes (http://localhost:3000/static/js/bundle.js:56686:5)
at Router (http://localhost:3000/static/js/bundle.js:56619:15)
at BrowserRouter (http://localhost:3000/static/js/bundle.js:55428:5)
at App
First time try to check if the product object it's not empty.
Or try every property with product?.title, product?.desc and so on
The issue has been solved by doing these changes.
const Product = () => {
const location = useLocation();
const Id = location.pathname.split('/')[2];
const [product, setProduct] = useState({});
useEffect(() => {
const getSingleProduct = async () => {
try {
const res = await publicRequest.get(`/products/find/${Id}`);
setProduct(res.data);
} catch (error) {
console.log(error);
}
}
getSingleProduct();
}, [Id]);
return (
<Container>
<Navbar />
<Announcment />
<Wrapper>
<ImageContainer>
<img src={product?.img ? require(`../../Assets/${product.img}`) : require('../../Assets/gray-men-shoes-1-free-img.jpg')} alt='' className='productImg2' />
</ImageContainer>
<InfoContainer>
<Title>{product?.title ? product.title : "Gray shoes"}</Title>
<Desc>{product?.desc ? product.desc : "abc"}</Desc>
<Price>$ {product?.price ? product.price : 20}</Price>
<FilterContainer>
<Filter>
<FilterTitle>Color</FilterTitle>
{product.color ? product.color.map((c, i) => (
<FilterColor color={c} key={i} />
))
: <><FilterColor color="black" /></>
}
</Filter>
<Filter>
<FilterTitle>Size</FilterTitle>
<FilterSize>
{product.size ? product.size.map((s, i) => (
<FilterSizeOption key={i}>{s}</FilterSizeOption>
))
: <> <FilterSizeOption >small</FilterSizeOption></>
}
</FilterSize>
</Filter>
</FilterContainer>
<AddContainer>
<AmountContainer>
<Remove style={{ cursor: "pointer" }} />
<Amount>1</Amount>
<Add style={{ cursor: "pointer" }} />
</AmountContainer>
<Button>ADD TO CART</Button>
</AddContainer>
</InfoContainer>
</Wrapper>
<Newsletter />
<Footer />
</Container>
);
}
export default Product

In React, how to setState a Data by using hook useState?

I am just getting started learning React Functional component and styled- component. I tried to setState detailePageData
const const [marketPriceData, setMarketPriceData] = useState([]);
and I tried to set up the marketPriceData by using JSON file.
useEffect(() => {
fetch(`/data/detailPageData.json`)
.then(res => res.json())
.then(data => setMarketPriceData(data.result.order_history));
}, []);
When I console.log marketPriceData. I got this
In here, I only need the price in each array. So, when I console.log(marketPriceData[0].price); I got 378000 what I expected.
Here is my main question, I only need each array price such as; 378000,341000,388000, etc.
I think I have to edit this part
useEffect(() => {
fetch(`/data/detailPageData.json`)
.then(res => res.json())
.then(data => setMarketPriceData(data.result.order_history));
}, []);
First, I think "Can I use foreach method? or for loop..?" I am not sure how to setup the logic to store the setMarketPriceData. Could you please help me with how to get the price what I expected?
Just in case, I will leave the whole code,
import React, { useState, useEffect } from 'react';
import styled from 'styled-components';
import { FaRegArrowAltCircleDown } from 'react-icons/fa';
import { Line } from 'react-chartjs-2';
import { Modal } from './components/Modal';
import TransitionHistoryModalStyling from '../ProductDetail/components/TransitionHistoryModalStyling';
import DropDownMenu from '../ProductDetail/components/DropDownMenu';
const options = {
scales: {
y: {
beginAtZero: true,
},
},
};
export default function MarketPrice() {
const [showModal, setShowModal] = useState(false);
const [marketPriceData, setMarketPriceData] = useState([]);
// https://github.com/reactchartjs/react-chartjs-2/blob/master/example/src/charts/Line.js
const data = {
labels: ['1', '2', '3', '4', '5', '6'],
datasets: [
{
label: 'MarketPrice',
data: marketPriceData,
fill: false,
backgroundColor: 'rgb(255, 99, 132)',
borderColor: 'rgba(255, 99, 132, 0.2)',
},
],
};
// useEffect(() => {
// let i = 1;
// if (i < detailPageData.order_history.length) {
// setMarketPriceData(detailPageData.order_history[i].price);
// }
// },[]);
const [detailPageData, setDetailPageData] = useState([]);
useEffect(() => {
fetch(`/data/detailPageData.json`)
.then(res => res.json())
.then(data => setDetailPageData(data.result));
}, []);
useEffect(() => {
fetch(`/data/detailPageData.json`)
.then(res => res.json())
.then(data => setMarketPriceData(data.result.order_history));
}, []);
console.log(marketPriceData);
console.log(marketPriceData[0].price);
// console.log(detailPageData.market_price[0].sizes[0].size);
// console.log(detailPageData.order_history);
// console.log(detailPageData.order_history.length);
// console.log(detailPageData.order_history[0].price);
// console.log(detailPageData.order_history.price);
const [currentMenuIndex, setCurrentMenuIndex] = useState(1);
const handleSelectedMenu = tabIndex => {
setCurrentMenuIndex(tabIndex);
};
const openModal = () => {
setShowModal(prev => !prev);
};
return (
<MarketPriceWrapper>
<TitleWrapper>
<MarketPriceTitle>시세</MarketPriceTitle>
<ShowAllSizes>
{/* <AllSize>230</AllSize>
<FaRegArrowAltCircleDown /> */}
<DropDownMenu className={DropDownMenu} />
</ShowAllSizes>
</TitleWrapper>
<SalesGraphWrapper>
<Line data={data} options={options} />
</SalesGraphWrapper>
<ButtonsWrapper>
<Button
isActive={currentMenuIndex === 1}
onClick={() => handleSelectedMenu(1)}
>
체결 거래
</Button>
<Button
isActive={currentMenuIndex === 2}
onClick={() => handleSelectedMenu(2)}
>
판매 입찰
</Button>
<Button
isActive={currentMenuIndex === 3}
onClick={() => handleSelectedMenu(3)}
>
구매 입찰
</Button>
</ButtonsWrapper>
<TableWrapper>
<TableColumnSetting>
<SizeName>사이즈</SizeName>
<PriceName>거래가</PriceName>
<DateName>거래일</DateName>
</TableColumnSetting>
<RowSection>
{/* {detailPageData.market_price &&
detailPageData.market_price.map(price => {
return console.log(price.sizes[0]);
<Size key={price.id}>
<Size>{price.sizes[price.id].size}</Size>
<Price>{price.sizes[price.id].avg_price}</Price>
<Date>{price.date}</Date>
</Size>
})} */}
<Size />
<Price>24,000원</Price>
<Date>99/11/17</Date>
</RowSection>
<RowSection>
<Size />
<Price>24,000원</Price>
<Date>99/11/17</Date>
</RowSection>
<RowSection>
<Size />
<Price>24,000원</Price>
<Date>99/11/17</Date>
</RowSection>
<RowSection>
<Size />
<Price>24,000원</Price>
<Date>99/11/17</Date>
</RowSection>
<RowSection>
<Size />
<Price>24,000원</Price>
<Date>99/11/17</Date>
</RowSection>
<OrderHistoryButton onClick={openModal}>
체결 내역 더보기
</OrderHistoryButton>
<Modal showModal={showModal} setShowModal={setShowModal}>
<TransitionHistoryModalStyling
detailPageDataMarket={detailPageData}
/>
</Modal>
</TableWrapper>
</MarketPriceWrapper>
);
}
const MarketPriceWrapper = styled.div`
width: 550px;
margin-top: 40px;
padding-left: 40px;
`;
const TitleWrapper = styled.div`
display: flex;
padding-top: 19px;
padding-bottom: 12px;
border-bottom: 1px solid #ebebeb;
`;
const SalesGraphWrapper = styled.div``;
const MarketPriceTitle = styled.span`
padding-top: 4px;
display: inline-block;
line-height: 16px;
font-weight: bold;
color: #222;
`;
const ShowAllSizes = styled.div`
margin-left: 370px;
`;
const AllSize = styled.span`
display: inline-block;
margin-right: 5px;
margin-left: 350px;
font-size: 18px;
`;
const ButtonsWrapper = styled.div`
display: flex;
justify-content: space-evenly;
margin-top: 40px;
border-radius: 10px;
background-color: #f4f4f4;
`;
const Button = styled.button`
display: block;
margin: 2px;
line-height: 16px;
padding: 7px 0 9px;
width: 400px;
font-size: 13px;
text-align: center;
border-radius: 8px;
border: none;
background-color: ${props => (props.isActive ? '#ffff' : '#f4f4f4')};
color: rgba(34, 34, 34, 0.8);
`;
const TableWrapper = styled.div`
margin-top: 40px;
`;
const TableColumnSetting = styled.div`
border-bottom: 1px solid #ebebeb;
padding-bottom: 9px;
text-align: right;
`;
const SizeName = styled.span`
display: inline-block;
margin-right: 250px;
font-size: 12px;
color: rgba(34, 34, 34, 0.5);
font-weight: 400;
`;
const PriceName = styled.span`
display: inline-block;
margin-right: 150px;
font-size: 12px;
color: rgba(34, 34, 34, 0.5);
font-weight: 400;
`;
const DateName = styled.span`
display: inline-block;
font-size: 12px;
color: rgba(34, 34, 34, 0.5);
font-weight: 400;
`;
const RowSection = styled.div`
margin-top: 4px;
text-align: right;
`;
const Size = styled.span`
display: inline-block;
margin-right: 240px;
color: #222;
font-size: 12px;
`;
const Price = styled.span`
display: inline-block;
margin-right: 130px;
color: #222;
font-size: 12px;
`;
const Date = styled.span`
display: inline-block;
color: #222;
font-size: 12px;
`;
const OrderHistoryButton = styled.button`
border: 1px solid #d3d3d3;
margin-top: 40px;
background-color: #ffffff;
color: rgba(34, 34, 34, 0.8);
font-weight: 400;
padding: 0 18px;
width: 500px;
height: 42px;
border-radius: 12px;
font-size: 14px;
`;
const const [marketPriceData, setMarketPriceData] = useState([]);
useEffect(() => {
fetch(`/data/detailPageData.json`)
.then(res => res.json())
.then(data => setMarketPriceData(data.result.order_history.map(item => item.price));
}, []);
maybe you can use map in your object data result.
data.result.order_history.map((item)=>{
return item.price
}
That will only get de price property in in your array.
setMarketPriceData(data.result.order_history.map((item)=>{
return item.price
})

In React, When I close the modal, I cannot scroll down/up

I am just getting started learning React with Function Component and Styled-Components. I created Modal Component and when I clicked the modal it shows up and I cannot scroll down/up(Background) but when I close the modal, I cannot scroll. I expect it should be work when I close the modal. Could you help me with what part something wrong?
const [showModal, setShowModal] = useState(false);
const [active, setActive] = useState(true);
const openModal = active => {
setShowModal(prev => !prev);
if (active) {
document.body.style.overflow = 'hidden';
} else {
document.body.style.overflow = 'auto';
}
};
<ShowAllSizes>
<AllSize>모든 사이즈</AllSize>
<FaRegArrowAltCircleDown // isActive={active} onClick={()=> openModal}
className="FaIconModal"
/>
<Modal showModal={showModal} setShowModal={setShowModal} />
</ShowAllSizes>
I will leave the whole code just in case
import React, { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
import styled from 'styled-components';
import { FaRegArrowAltCircleDown } from 'react-icons/fa';
import { Modal } from './components/Modal';
export default function ColumnTop() {
const [showModal, setShowModal] = useState(false);
const [active, setActive] = useState(true);
const openModal = active => {
setShowModal(prev => !prev);
if (active) {
document.body.style.overflow = 'hidden';
} else {
document.body.style.overflow = 'auto';
}
};
return (
<RightSideSection>
<ColumnTopSection>
<TitleBox>
<BrandName>Jordan</BrandName>
<EngName>Jordan 1 Retro High OG Bordeaux</EngName>
<KrName>조던 1 레트로 하이 OG 보르도</KrName>
</TitleBox>
<FigureWrap>
<DetailSize>
<SizeInKorean>사이즈</SizeInKorean>
<ShowAllSizes>
<AllSize>모든 사이즈</AllSize>
<FaRegArrowAltCircleDown
// isActive={active}
onClick={() => openModal}
className="FaIconModal"
/>
<Modal showModal={showModal} setShowModal={setShowModal} />
</ShowAllSizes>
</DetailSize>
<DetailPrice>
<TransactionPriceKorean>최근 거래가</TransactionPriceKorean>
<PriceInfo>
<CurrentPrice>248,000</CurrentPrice>
<PricePunctuation>6000원(-2.4%)</PricePunctuation>
</PriceInfo>
</DetailPrice>
<ButtonWrapper>
<Button>
<ButtonDivision>
<LeftSide>
<BtnTitle to="/order">구매</BtnTitle>
</LeftSide>
<RightSide>
<OrderPrice>23500원</OrderPrice>
<OrderStatusName>즉시 구매가</OrderStatusName>
</RightSide>
</ButtonDivision>
</Button>
<Button primary>
<ButtonDivision>
<LeftSide>
<BtnTitle to="/order">판매</BtnTitle>
</LeftSide>
<RightSide>
<OrderPrice>11500원</OrderPrice>
<OrderStatusName>즉시 판매가</OrderStatusName>
</RightSide>
</ButtonDivision>
</Button>
</ButtonWrapper>
</FigureWrap>
</ColumnTopSection>
</RightSideSection>
);
}
const ShowAllSizes = styled.div``;
const RightSideSection = styled.div`
padding-left: 40px;
`;
const ColumnTopSection = styled.div`
display: flex;
flex-direction: column;
`;
const TitleBox = styled.div`
display: flex;
flex-direction: column;
`;
const BrandName = styled.span`
display: inline-block;
vertical-align: top;
line-height: 19px;
padding-top: 1px;
margin-bottom: 9px;
font-size: 18px;
font-weight: 800;
border-bottom: 2px solid #222;
width: 61px;
height: 21px;
`;
const EngName = styled.span`
margin-bottom: 4px;
font-size: 18px;
font-weight: 400;
`;
const KrName = styled.span`
line-height: 17px;
font-size: 14px;
color: rgba(34, 34, 34, 0.5);
`;
const FigureWrap = styled.div`
width: 500px;
`;
const DetailSize = styled.div`
padding-top: 19px;
padding-bottom: 12px;
border-bottom: 1px solid #ebebeb;
`;
const SizeInKorean = styled.span`
padding-top: 4px;
display: inline-block;
line-height: 16px;
font-size: 13px;
color: rgba(34, 34, 34, 0.8);
`;
const AllSize = styled.span`
display: inline-block;
margin-right: 5px;
margin-left: 392px;
font-size: 18px;
`;
const FaIconModal = styled.button``;
const DetailPrice = styled.div`
display: flex;
margin-top: 4px;
`;
const TransactionPriceKorean = styled.span`
position: absolute;
width: 60px;
padding-top: 5px;
height: 7px;
font-size: 13px;
color: rgba(34, 34, 34, 0.8);
`;
const PriceInfo = styled.div`
display: flex;
flex-direction: column;
margin-left: 330px;
`;
const CurrentPrice = styled.span`
margin-left: 100px;
margin-top: 4px;
`;
const PricePunctuation = styled.span`
color: #31b46e;
margin-left: 110px;
`;
const ButtonWrapper = styled.div`
margin-top: 15px;
`;
const ButtonDivision = styled.div`
display: flex;
`;
const Button = styled.button`
background: ${props => (props.primary ? '#41B979' : '#EF6253')};
width: 235px;
height: 40px;
margin-right: 15px;
padding: 0 10px;
border: none;
border-radius: 5px;
`;
const LeftSide = styled.div`
margin-top: 3px;
left: 5px;
`;
const BtnTitle = styled(Link)`
font-weight: bold;
color: #fff;
text-decoration: none;
`;
const RightSide = styled.div`
margin-left: 10px;
border-left: 1px solid silver;
color: #fff;
`;
const OrderPrice = styled.div`
margin-left: 10px;
`;
const OrderStatusName = styled.div`
margin-left: 20px;
`;
This is my Modal Component
import React, { useRef, useState, useEffect, useCallback } from 'react';
import styled from 'styled-components';
import { MdClose } from 'react-icons/md';
export const Modal = ({ showModal, setShowModal }) => {
const modalRef = useRef();
const [detailPageData, setDetailPageData] = useState([]);
useEffect(() => {
fetch(`/data/detailPageData.json`)
.then(res => res.json())
.then(data => setDetailPageData(data.result.price_by_size));
}, []);
const closeModal = e => {
if (modalRef.current === e.target) {
setShowModal(false);
}
};
const keyPress = useCallback(
e => {
if (e.key === 'Escape' && showModal) {
setShowModal(false);
}
},
[setShowModal, showModal]
);
useEffect(() => {
document.addEventListener('keydown', keyPress);
return () => document.removeEventListener('keydown', keyPress);
}, [keyPress]);
// console.log(setDetailPageData);
return (
<div>
{showModal ? (
<Background onClick={closeModal} ref={modalRef}>
<ModalWrapper showModal={showModal}>
<SizeModalContent>
<Title>사이즈</Title>
<ButtonWrapper>
{detailPageData.map(({ id, title, price }) => {
return (
<Button key={id}>
<Size>{title}</Size>
<Price>{price}</Price>
</Button>
);
})}
</ButtonWrapper>
</SizeModalContent>
<CloseModalButton
aria-label="Close modal"
onClick={() => setShowModal(prev => !prev)}
/>
</ModalWrapper>
</Background>
) : null}
</div>
);
};
const Background = styled.div`
position: fixed;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
left: -0px;
top: -0px;
background: rgba(0, 0, 0, 0.8);
z-index: 10;
`;
const ModalWrapper = styled.div`
width: 400px;
height: 400px;
background: #fff;
color: #000;
border-radius: 10px;
`;
const SizeModalContent = styled.div`
margin-left: 20px;
margin-right: 20px;
`;
const Title = styled.div`
margin: 15px;
font-weight: 700;
color: #000;
text-align: center;
`;
const ButtonWrapper = styled.div`
margin: 10px 0px;
display: grid;
grid-template-columns: repeat(3, 33%);
`;
const Button = styled.button`
width: 100px;
height: 35px;
margin-left: 5px;
margin-bottom: 5px;
border: 1px solid #d3d3d3;
border-radius: 10px;
background-color: #fff;
`;
const Size = styled.span`
display: block;
font-weight: 700px;
`;
const Price = styled.span`
color: red;
`;
const CloseModalButton = styled(MdClose)`
cursor: pointer;
position: absolute;
top: 350px;
right: 800px;
font-size: 20px;
/* top: -50px;
right: -360px;
width: 32px;
height: 32px; */
`;
Edit1: Copy and Past my Modal.js

× Error: Element type is invalid: expected a string (for built-in components)

Getting this below error in my code. I am unable to find what is the error. Please help.
×
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of `LoginForm`..
LoginForm.js
import React from "react";
import { BoxContainer, FormContainer, MutedLink, SubmitButton, Input } from "./common";
import { Marginer } from "../marginer";
export function LoginForm(props) {
return (
<BoxContainer>
<FormContainer>
<Input type ="email" placeholder="Email" />
<Input type ="password" placeholder="Password" />
<Marginer direction="vertical" margin={5} />
<MutedLink href="#">Forget your password?</MutedLink>
<Marginer direction="vertical" margin="lem" />
<SubmitButton type="submit">Signin</SubmitButton>
</FormContainer>
</BoxContainer>
);
}
index.js
import React from 'react'
import styled from 'styled-components'
import { LoginForm } from './loginForm';
const BoxContainer = styled.div`
width: 280px;
min-height: 550px;
display: flex;
flex-direction: column;
border-radius: 19px;
background-color: #fff;
box-shadow: 0 0 2px rgba(15, 15, 15, 0.28);
position: relative;
overflow: hidden;
`;
const TopContainer =styled.div`
width: 100%;
height: 250px;
display: flex;
flex-direction: column;
justify-content: flex-end;
padding: 0 1.8em;
padding-bottom: 5em;
`;
const BackDrop = styled.div`
position: absolute;
display: flex;
flex-direction: column;
width: 160%;
height: 550px;
border-radius: 50%;
top: -290px;
left: -70px;
transform: rotate(60deg);
background: rgb(241, 196, 15);
background: linear-gradient(
58deg,
rgba(241,196,15,1) 20%,
rgba(243,172,18,1) 100%
)
`;
const HeaderContainer = styled.div`
width:100%;
display: flex;
flex-direction:column;
margin:auto;
`;
const HeaderText = styled.h2`
font-size: 30px;
font-weight: 600;
line-height: 1.24;
color: #fff;
z-index: 10;
margin: 0;
margin-right: 218px;
`;
const SmallText = styled.h5`
color:#ece5e5;
font-weight: 500;
font-size: 11px;
z-index: 10;
margin:0;
margin-right: 147px;
margin-top: 6px;
`;
const InnerContainer = styled.div`
width: 100%;
display: flex;
flex-direction:column;
`;
export function AccountBox(props) {
return (
<BoxContainer>
<TopContainer>
<BackDrop />
<HeaderContainer>
<HeaderText>Welcome</HeaderText>
<HeaderText>Back</HeaderText>
<SmallText>please sign-in to continue!</SmallText>
</HeaderContainer>
</TopContainer>
<InnerContainer>
<LoginForm />
</InnerContainer>
</BoxContainer>
);
}
marginer.js
import React from "react";
import styled from "styled-components";
const HorizontalMargin = styled.span`
display: flex;
width: ${({ margin }) =>
typeof margin === "string" ? margin : `${margin}px`};
`;
const VerticalMargin = styled.span`
display: flex;
height: ${({ margin }) =>
typeof margin === "string" ? margin : `${margin}px`};
`;
function Marginer(props) {
const { direction } = props;
if (direction === "horizontal") return <HorizontalMargin {...props} />;
else {
return <VerticalMargin {...props} />;
}
}
Marginer.defaultProps = {
direction: "horizontal",
};
export { Marginer };

Resources