So I have a very complex structure but I think I'm very clear on the issue and thus I'm mentioning the minimum requirement for the issue.
Consider following is a component that I've used.
const SalesOrderLineItems = ({
...requiredProps,
}) => {
const [productLines, setProductLines] = useState([])
const [shippingLines, setShippingLines] = useState([])
const [totals, setTotals] = useState({})
const [discounts, setDiscounts] = useState([])
useEffect(() => {
// My main concern is this. I'd expect this to be triggered whenever I use setState in child component.
console.log(' ~ productLines:', productLines)
}, [productLines])
const updateProductLines = useCallback((lines) => setProductLines(lines), [])
const updateShippingLines = useCallback((lines) => setShippingLines(lines), [])
return (
<div className="SalesOrderLineItems">
<SalesOrderProductLines
updateProductLines={updateProductLines}
{...otherProps} />
<SalesOrderShippingLines
updateShippingLines={updateShippingLines}
productLines={productLines} // Mainly for calculative purposes, Never used in rendering
{...otherProps}
/>
<SalesOrderDiscounts
discounts={discounts}
{...otherProps}
/>
<SalesOrderTotals
totals={totals}
{...otherProps}
/>
</div>
)
}
export default SalesOrderLineItems
Now in SalesOrderProductLines
component, I've used React Hook Form's watch which updates the productLines via passed prop like below.
useEffect(() => {
const subscription = watch((value, { name, type }) => {
// some business logic
updateProductLines(value.lines)
console.log(' ~ lines updated:', value.lines) // This gets logged with the latest values, So I'm assured that the above state update works fine!
})
return () => subscription.unsubscribe()
}, [watch])
I think that my code uses uncontrolled inputs so it doesn't trigger any re-rendering thus preventing parent component to trigger the effect for productLines!
Do someone know how I can utilize something to find a way to listen to productLines change without triggering re-rendering for the performance changes? As I'm just going to set totals
by performing calculations on the latest productLines, shippingLines and discounts
.
Codesandbox can be found here