简体   繁体   中英

can someone explain to me how the async works in this scenario of useEffect?

i have an onClick event within a child:

onClick={()=>{ //2. an image is clicked, and the choice is added to the choiceOrder state, and then a jsonupdate is called -- 3. in ChooseBy.js
    //onclick, add or remove the choice
    choosebyprops.setChoiceOrder(choiceOrder => {
        if (choiceOrder.includes(attrprops.attrChoice)) {
            const choiceIndex = choiceOrder.findIndex(attrprops.attrChoice);
            choosebyprops.setJsonList((_, i) => i !== choiceIndex+1)
            return choiceOrder.filter(list => list !== attrprops.attrChoice);
        } else {
            const newList = [...choiceOrder, attrprops.attrChoice];
            return newList
        }
    });
    attrprops.setSelectedAttr( selectedAttr=>(selectedAttr!==attr ? attr : null)  );
}}

after that click, i need a list to update:

useEffect(()=>{
    if(selectedAttr==null){
        publishprops.setBuysideChoice( buysideChoice => ({'car_option':buysideChoice['car_option'],'zip_code':buysideChoice['zip_code']}) );
        publishprops.setAttrNumber(2);
    }
    else {
        publishprops.setBuysideChoice( buysideChoice => ({...buysideChoice,"body_type": selectedAttr}) );
        publishprops.setAttrNumber(4);
    };
},[selectedAttr])

useEffect(()=>{
    const choiceOrder = choosebyprops.choiceOrder;
    if (choiceOrder.includes(attrChoice) && choiceOrder[choiceOrder.length-1]==attrChoice) {
        console.log('this json1',choosebyprops.jsonList)
            choosebyprops.setJsonList(jsonList => [...jsonList, UpdateJson(allprops)]); //delayed
    }
},[choosebyprops.choiceOrder])

but when the UpdateJson(allprops) function fires in the second useEffect - it's delayed. if i make a small change and save, i'll see the update in the console.log - but it doesn't fix the issue.

i've also tried adding this:

const [rerender, setRerender] = useState(false);

and adding setRerender(!rerender) in the same useEffect.

i've also tried to create a useEffect in the parent:

useEffect(()=>{
    console.log(jsonList)
},[publishprops.buysideChoice])

so...i know that useEffect is an async function. what i dont understand is how to adjust that. i read some about how you need to use the previous state. i thought i had that taken care of with the call back: choosebyprops.setJsonList(jsonList => [...jsonList, UpdateJson(allprops)]);

really confused about this whole concept.

ok, after some playing around, i decided to rerender the parent component and see what would happen...wouldn't you guess it - that's what worked.

I added this to the parent:

useEffect(()=>{
    setRerender(!rerender)
},[choiceOrder])

and then i passed down rerender to the child. then i changed the useEffect of the child to fire if anything happened to the parent's rerender state.

useEffect(()=>{
    const choiceOrder = choosebyprops.choiceOrder;
    const setJsonList = choosebyprops.setJsonList
    if (choiceOrder.includes(attrChoice) && choiceOrder[choiceOrder.length-1]==attrChoice) {
        console.log('this json1',choosebyprops.jsonList)
            setJsonList(jsonList => [...jsonList, UpdateJson(allprops)]); //delayed
    }
},[choosebyprops.rerender])

now...to me it seems like im rerendering it multiple times - but hey it works.

still would love an explanation, because from what i gather:

  1. the child updates a parent's state
  2. the parent for some reason didn't rerender - so you have to make it rerender
  3. once the parent rerenders, the async function of the child completes

this sounds really wrong to me :/

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