Although case one and case two shown below both work, I have these two questions (the first question is why I’m here… I’m happy to ask the second one on Stack Overflow, but it seems like the second one might be worth considering vis a vis the ideal pattern for the situation that comes up below):
Question #1
What are the considerations behind deciding between passing the out of the box setWhatever
from useState()
down to a child (see case one below) versus creating a custom handleWhatever
function to pass to the child, where the handleWhatever
function uses setWhatever
within it (see case two below)?
Question #2
Both cases result in the warning shown below… which may or may not mean that the best practice pattern for having a child update a parent’s state is something other than one of my two cases… here is the warning:
Warning: Cannot update a component (Test
) while rendering a different component (DetermineValue
). To locate the bad setState()
call inside DetermineValue
, follow the stack trace
Definitely React is about passing state down from parent to child. But after reiterating that fact, it seems like we are always left with countless examples where a function is passed from parent to child for the purpose of keeping a parent aware of a certain value within the child. My question is about such cases where a function needs to be passed down to a child. (If someone is 100% sure that all such cases of passing a function to a child are misguided… then, of course, I’m open to learning about why!! I don’t claim to have absolute certainty that it is a sound pattern for functions to be passed to children for the purposes of updating a parent).
Case #1
// Test.js (parent, case one)
import React, { useState } from 'react';
import DetermineValue from './DetermineValue';
const Test = () => {
const (importantValue, setImportantValue) = useState();
console.log(importantValue);
return <DetermineValue setImportantValue={setImportantValue} />;
};
export default Test;
// DetermineValue.js (child, case one)
import React from 'react';
const DetermineValue = ({ setImportantValue }) => {
setImportantValue('Important Data');
return <></>;
};
export default DetermineValue;
Case #2
// Test.js (parent, case two)
import React, { useState } from 'react';
import DetermineValue from './DetermineValue';
const Test = () => {
const (importantValue, setImportantValue) = useState();
const handleSetImportantValue = (importantValueQuickPass) => {
setImportantValue(importantValueQuickPass);
};
console.log(importantValue);
return <DetermineValue handleSetImportantValue={handleSetImportantValue} />;
};
export default Test;
// DetermineValue.js (child, case one)
import React from 'react';
const DetermineValue = ({ handleSetImportantValue }) => {
handleSetImportantValue('Important Data');
return <></>;
};
export default DetermineValue;