I am working on the ReactJS Project and in there I want a component which does something every time it renders but not every time something change in it.
Dashboard.js
import React, { useCallback, useEffect, useState } from 'react'
import Product from './Product'
import { database } from '../../firebase/firebase'
const Dashboard = () => {
const [defaults, setDefaults] = useState([])
const [firstKey, setFirstKey] = useState('')
const [lastKey, setLastKey] = useState('')
const convertToArray = (data) => {
const tempArray = []
for (let product in data) {
tempArray.push({
id: product,
amount: data[product]['amount'],
productName: data[product]['productName']
})
}
return tempArray
}
const nextButtonListener = async () => {
const nextData = await (await database.ref('/system').orderByKey().startAfter(lastKey).limitToFirst(10).once('value')).val()
const keys = Object.keys(nextData)
setFirstKey(keys[0])
setLastKey(keys[keys.length - 1])
setDefaults(oldDefaults => convertToArray(nextData))
}
const previousButtonListener = async () => {
const previousData = await (await database.ref('/system').orderByKey().endBefore(firstKey).limitToLast(10).once('value')).val()
const keys = Object.keys(previousData)
setFirstKey(keys[0])
setLastKey(keys[keys.length - 1])
setDefaults(oldDefaults => convertToArray(previousData))
}
const firstPageLoad = async () => {
const firstPage = await (await database.ref('/system').orderByKey().limitToFirst(10).once('value')).val()
const keys = Object.keys(firstPage)
setFirstKey(keys[0])
setLastKey(keys[keys.length - 1])
setDefaults(oldDefaults => convertToArray(firstPage))
}
useEffect(() => {
console.log('Called')
firstPageLoad()
document.querySelector('#nextButton').addEventListener('click', nextButtonListener)
document.querySelector('#previousButton').addEventListener('click', previousButtonListener)
return () => {
document.querySelector('#nextButton').removeEventListener('click', nextButtonListener)
document.querySelector('#previousButton').removeEventListener('click', previousButtonListener)
}
}, [])
return (
<div>
<h2>Dashboard</h2>
{defaults.map(product => {
return (<Product key={product.id} product={{ id: product.id, amount: product.amount, name: product.productName }} />)
}
)}
<button id="nextButton">Next</button>
<button id="previousButton">Previous</button>
</div>
)
}
export default Dashboard
Product.js
import React, { useContext, useEffect } from 'react'
import { cartContext } from '../context/appContext'
import { addProduct, removeProduct } from '../actions/cart'
const Product = ({ product, isCart }) => {
const { cartDispatch } = useContext(cartContext)
return (
<div>
<h3>{product.name}</h3>
<p>Amount: {product.amount}</p>
{
isCart ?
(<button onClick={() => { cartDispatch(removeProduct(product.id)) }}>Remove</button>) : (<button onClick={() => { cartDispatch(addProduct(product)) }}>Add to Cart</button>)
}
</div>
)
}
export default Product
Now, everything renders perfectly but whenever I click on the button in Product , useEffect in Dashboard runs even though I have provided empty array as second arguement in useEffect method in MyComponent