Reputation: 877
I have a higher order functional component in my app that passes JSON to it's child component. I am using react Hooks to manage state. I can't use componentDidUpdate since this is not a class component.
I'm using useEffect()
to get it to process the JSON on initial render, but after that I can't seem to get it to update. I've confirmed the PROPS are indeed changing and the JSON is unique (it changes on the click of a button).
Here is my code:
function FormSection(props) {
const [questions, updateQuestions] = useState([]);
const [sectionJSON, updateSectionJSON] = useState(props.json);
const fetchQuestionsData = json => {
/* API CALL TRANSFORM JSON INTO HTML FOR USE ELSEWHERE IN THE APP */
};
useEffect(() => {
fetchQuestionsData(sectionJSON);
}, [sectionJSON]);
...
}
I've also tried changing the useEffect()
hook to use props directly:
useEffect(() => {
fetchQuestionsData(props.json);
}, [props.json]);
The parent componenet is calling it as follows:
<FormSection key={i} json={newJSON} />
Is there something obvious I am missing?
Upvotes: 0
Views: 1698
Reputation: 20755
When you set,
const [sectionJSON, updateSectionJSON] = useState(props.json);
is equivalent to,
constructor(props){
super(props);
this.state = {
sectionJSON: props.json
}
}
So your sectionJSON
will set only once and any subsequent change in props.json
will not change sectionJSON
.
So this will execute only once, and not when props.json
changes
useEffect(() => {
fetchQuestionsData(sectionJSON);
}, [sectionJSON]);
To make this work you need to pass props.json
to your useEffect
hook as,
useEffect(() => {
fetchQuestionsData(props.json);
}, [props.json]);
Doing this will not re-render your component, because your component's state
is not changing, like we do using componentDidUpdate
in class based component, so you should set your state in fetchQuestionsData
like,
const fetchQuestionsData = json => {
/* API CALL TRANSFORM JSON INTO HTML FOR USE ELSEWHERE IN THE APP */
updateSectionJSON(json); //This will re-render your component.
};
Upvotes: 3