Consider the following:
I have a parent functional component with a nested child component,
function Parent(){
const [isFlagTrue, setIsFlagIsTrue] = useState(false);
const handleFlagChange = (bool) => setIsFlagIsTrue(bool)
useEffect(() => {
console.log("isFlagTrue ", isFlagTrue);
}, [isFlagTrue])
return (
<Child handleFlagChange={handleFlagChange} />
)
}
In the Child I'm making an async call to populate a data-table;
import { useDispatch } from 'react-redux';
function Child({handleFlagChange}) {
const dispatch = useDispatch();
const componentIsMounted = useRef(true)
const [rows, setRows] = useState([]);
useEffect(() => {
if (currentProductItem && currentProductItem.value != null) {
dispatch(getClientVariables(currentProductItem.value)).then(r => {
rawData.current.Rows = r.payload;
dispatch(getClientVariableTypesAll(currentProductItem.value)).then(r => {
rawData.current.ClientDataVariableTypes = r.payload.map(r => {
return {
value: r.ClientDataVariableTypeID,
label: r.ClientDataVariableTypeName
}
});;
setRows(rawData.current.Rows);
console.log('rawData', rawData);
});
});
}
}, [currentProductItem, justSavedNewVariableTypes, justSavedGrid]);
}
useEffect(() => {
console.log("typeof handleFlagChange ", typeof handleFlagChange);
console.log("rows ", rows);
// if (componentIsMounted.current) {
// var flag = rows.some(item => item.ClientDataVariableTypeName == null)
// handleFlagChange(flag)
// }
if (Array.isArray(rows) && typeof handleFlagChange != 'undefined') {
console.log("foo ");
var flag = rows.some(item => item.ClientDataVariableTypeName == null)
handleFlagChange(flag)
}
}, []);
useEffect(() => {
return () => {
componentIsMounted.current = false
}
},[])
....other code & rendering
}
I am expecting the isFlagTrue
console in the useEffect of the parent to fire when the rows have been validated in the child by the return value of the some
function on the array of rows.
I have tried two solutions one is insuring the <Child/>
is mounted (and having the data call being full-filled) by setting a ref to true using useRef()
.
In Child: const componentIsMounted = useRef(true)
useEffect(() => {
console.log("typeof handleFlagChange ", typeof handleFlagChange);
if (componentIsMounted.current) {
var flag = rows.some(item => item.ClientDataVariableTypeName == null)
handleFlagChange(flag)
}
}, []);
useEffect(() => {
return () => {
componentIsMounted.current = false
}
},[])
But I get TypeError: handleFlagChange is not a function
So then I tried:
useEffect(() => {
console.log("typeof handleFlagChange ", typeof handleFlagChange);
if (componentIsMounted.current && typeof handleFlagChange != 'undefined' && typeof handleFlagChange != 'undefined') {
console.log("foo ");
var flag = rows.some(item => item.ClientDataVariableTypeName == null)
handleFlagChange(flag)
}
}, []);
But that yields:
typeof handleFlagChange undefined. <---In the Child
isFlagTrue false <--- In Parent
Any ideas?
handleFlagChange !== undefined
or!!handleFlagChange
to check ifhandleFlagChange
is defined or not, nottypeof
. - Lukas Bachif (componentIsMounted.current && handleFlagChange)
- Rahul KumarhandleFlagChange
to be undefined. - Dave Newton