简体   繁体   中英

React.JS - Child Componenet Not Updating When Recieving Props (Function Components)

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?

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.
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM