Reputation: 35
I'm building an e-commerce website. Now, I'm working on creating the navigation bar that has the names of the available categories, and once a category is checked (clicked). All the items that have that are listed in the specific category will render in the same page. Right now, I'm working on rendering the names of the products. Here is my code for each part which are navigation bar, all items page, item card.
function NavBar() {
// To fill the tabs for the navigation bar
useEffect(() => {
fetchQuery(`
query{
categories{
name
}
}
`).then(data => {
var count = 1
data.data.categories.forEach(categories=> {
// <input className='radio-category' id='all' type='radio' name="nav"/>
// <label for='all' className='category-label'> <h3 className="tab-text">ALL</h3> </label>
const input = document.createElement('input')
input.className = 'radio-category'
input.id = categories.name
input.type = 'radio'
input.name = 'nav-categories'
// input.onclick = function (){
// console.log(input.checked, input.id)
// AllItems()
// }
input.href = '/'
const label = document.createElement('label')
label.htmlFor = categories.name
label.className = 'category-label'
const categoryLabelText = document.createElement('h5')
categoryLabelText.className = 'tab-text'
categoryLabelText.innerHTML = categories.name.toUpperCase()
// put categoryLabelText inside label
label.append(categoryLabelText)
// render all elements to the nav bar
document.getElementById("leftNav").append(input)
document.getElementById("leftNav").append(label)
// check the first element always
if (count == 1){
input.checked = true
label.checked = true
}
count += 1
})
})
})
// for currency options
useEffect(() => {
fetchQuery(`
query{
currencies
}
`).then(data => {
const selectBox = document.getElementById("currencySelector")
data.data.currencies.forEach(currencies=>{
const option = document.createElement('option')
option.value = currencies
option.innerText = getSymbolFromCurrency(currencies) + currencies
selectBox.append(option)
})
})
})
return (
<nav id = "NavBar">
<div id="NavBar-content">
<div className = "leftSide" id = "leftNav">
{/*<input className='radio-category' id='all' type='radio' name="nav"/>*/}
{/*<label for='all' className='category-label'> <h3 className="tab-text">ALL</h3> </label>*/}
</div>
<div className = "centerSide">
<a href="/">
{/*<img src={logo} />*/}
Logo
</a>
</div>
<div className = "rightSide">
<select className="currencySelector" id="currencySelector">
</select>
</div>
</div>
</nav>
);
}
export default NavBar;
All Items page, which is the container of all the items
function AllItems(category) {
// useEffect(() => {
//
//
// },[])
fetchQuery(`
query{
category{
products{
name
id
category
}
}
}
`).then(data => {
// console.log(data.data)
data.data.category.products.forEach(products => {
// console.log(products.name)
if ( document.getElementById(products.category).checked ){
<ItemCard itemName={products.name} id={products.id}/>
}
})
})
return (
<div className="itemCard" id="itemCard">
</div>
)
}
export default AllItems;
Item card container
function ItemCard({itemName, id}) {
return (
<>
<a href='/${id}'>
<h6 id="item-name">
{itemName}
</h6>
</a>
</>
);
}
export default ItemCard;
I don't know why nothing works with me. Is there any missing function or something? Please let me know.
Upvotes: 0
Views: 67
Reputation: 394
To expand on my comments, here's a contrived version of what you may do:
function MyComponent({ checkedCategories }) {
const [products, setProducts] = useState([])
useEffect(() => {
myFetchFunction()
.then(data => {
setProducts(data.products)
})
}, [])
const productsToDisplay = products.filter(
product => checkedCategories.includes(product.category)
)
return (
<div>
{productsToDisplay.map(product => (
<SomeProductComponent key={product.id} product={product} />
))}
</div>
)
}
Separating fetching of data, setting of state, transforming data and rendering are best separated to give a clearer picture of your intent within the component. I hope it's abstract enough to give you something to work on for all your pages.
Upvotes: 1