I am working on Header onscroll
functionality. When user scroll
down then background white
should apply and when user scroll up
to 0
then background transparent
colour should apply. I am sending two objects via dispatch
actions and getting it through useSelector
. But I get undefined
in bg
property in console. Please correct me what I am doing wrong here. Below is the code.
HEADER.JS
import React, { useEffect } from 'react';
import './header.css';
import { useDispatch, useSelector } from 'react-redux';
import { changeBG, fetchHeader } from '../../redux/actions/header/HeaderActions';
const Header = () => {
const dispatch = useDispatch();
const logo = useSelector((state) => state.headerReducer.hData.logo);
const parentLinks = useSelector((state) => state.headerReducer.hData.parentLinks);
const bgColor = useSelector((state) => state.headerReducer.bg);
console.log(bgColor);
useEffect(() => {
getHeaderApi();
window.addEventListener('scroll', changeNavBG);
return () => {
window.removeEventListener('scroll', changeNavBG);
};
}, []);
const getHeaderApi = async () => {
// const apikey = process.env.REACT_APP_API_KEY;
// const response = await fetch(
// `https://api.json-generator.com/templates/jy5YJ7qSuzOt/data?access_token=${apikey}`
// );
const response = await fetch(`http://localhost:8000/homepage`);
const data = await response.json();
// console.log(data);
dispatch(fetchHeader(data.header));
};
const changeNavBG = () => {
if (window.scrollY.toFixed() > 0) {
dispatch(changeBG({ bg: 'bg-white' }));
} else {
dispatch(changeBG({ bg: 'bg-transparent' }));
}
};
return (
<>
<div className={`dvHeader ${bgColor}`}>
<div className="container-lg">
<div className="row align-items-center pt-1">
<div className="col d-lg-none">
<i className="fa-solid fa-bars"></i>
</div>
<div className="col col-lg-auto text-center text-lg-left">
<img width={50} src={logo && logo.url} alt="" />
</div>
<div className="dvSlideMenu col-lg-auto px-0 px-lg-3">
<button className="btn btn-black closeBtn d-lg-none">
<i className="fa-solid fa-xmark"></i>
</button>
<ul className="dvMenu">
{parentLinks &&
parentLinks.map((item) => {
const { id, link } = item;
return (
<li key={id}>
<a href="">{link}</a>
</li>
);
})}
</ul>
</div>
<div className="col col-lg-auto ml-lg-auto text-right">
<i className="fa-solid fa-cart-shopping"></i>
</div>
</div>
</div>
</div>
</>
);
};
export default Header;
HEADER ACTIONS
export const fetchHeader = (data) => {
return {
type: 'FETCH_HEADER',
payload: data,
};
};
export const changeBG = (bgColor) => {
return {
type: 'CHANGE_NAV_BG',
payload: bgColor,
};
};
HEADER REDUCER
const headeriState = {
hData: {},
bgc: { bg: 'bg-transparent' },
};
export const headerReducer = (state = headeriState, action) => {
switch (action.type) {
case 'FETCH_HEADER':
return {
...state,
hData: action.payload, //data update
};
case 'CHANGE_NAV_BG':
return {
...state,
bgc: action.payload, //data update
};
default:
return state;
}
};
INDEX.CSS
/*header bg class change on scroll*/
.bg-white {
background-color: rgba(255, 255, 255, 90%);
}
.bg-transparent {
background-color: rgba(0, 0, 0, 0);
}
It should probably look like this hence headeriState
is the same as state
const bgColor = useSelector((state) => state.bgc.bg);