может ли кто-нибудь объяснить мне, как работает асинхронность в этом сценарии эффекта использования?

#javascript #reactjs #next.js

Вопрос:

у меня есть событие onClick внутри ребенка:

 onClick={()=gt;{ //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 =gt; {  if (choiceOrder.includes(attrprops.attrChoice)) {  const choiceIndex = choiceOrder.findIndex(attrprops.attrChoice);  choosebyprops.setJsonList((_, i) =gt; i !== choiceIndex 1)  return choiceOrder.filter(list =gt; list !== attrprops.attrChoice);  } else {  const newList = [...choiceOrder, attrprops.attrChoice];  return newList  }  });  attrprops.setSelectedAttr( selectedAttr=gt;(selectedAttr!==attr ? attr : null) ); }}  

после этого щелчка мне нужен список для обновления:

 useEffect(()=gt;{  if(selectedAttr==null){  publishprops.setBuysideChoice( buysideChoice =gt; ({'car_option':buysideChoice['car_option'],'zip_code':buysideChoice['zip_code']}) );  publishprops.setAttrNumber(2);  }  else {  publishprops.setBuysideChoice( buysideChoice =gt; ({...buysideChoice,"body_type": selectedAttr}) );  publishprops.setAttrNumber(4);  }; },[selectedAttr])  useEffect(()=gt;{  const choiceOrder = choosebyprops.choiceOrder;  if (choiceOrder.includes(attrChoice) amp;amp; choiceOrder[choiceOrder.length-1]==attrChoice) {  console.log('this json1',choosebyprops.jsonList)  choosebyprops.setJsonList(jsonList =gt; [...jsonList, UpdateJson(allprops)]); //delayed  } },[choosebyprops.choiceOrder])  

но когда UpdateJson(allprops) функция срабатывает во втором эффекте использования — она задерживается. если я внесу небольшое изменение и сохраню, я увижу обновление в console.log, но это не исправит проблему.

я также попытался добавить это:

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

и добавление setRerender(!rerender) того же эффекта использования.

я также попытался создать эффект использования в родительском:

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

итак…я знаю, что useEffect-это асинхронная функция. чего я не понимаю, так это как это исправить. я читал кое-что о том, как вам нужно использовать предыдущее состояние. я думал, что позаботился об этом с ответным звонком: choosebyprops.setJsonList(jsonList =gt; [...jsonList, UpdateJson(allprops)]);

действительно запутался во всей этой концепции.

Ответ №1:

хорошо, после некоторой игры я решил повторно запустить родительский компонент и посмотреть, что произойдет…вы бы не догадались — вот что сработало.

Я добавил это к родительскому:

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

а потом я перешел rerender к ребенку. затем я изменил эффект использования ребенка, чтобы он срабатывал, если что-то случится с состоянием повторного вызова родителя.

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

now…to мне кажется, что я повторяю это несколько раз, но, эй, это работает.

все равно хотелось бы получить объяснение, потому что из того, что я понял:

  1. ребенок обновляет состояние родителя
  2. родитель по какой — то причине не переоформил-поэтому вы должны сделать его переоформленным
  3. как только родитель повторит отправку, асинхронная функция дочернего элемента завершится

для меня это звучит действительно неправильно :/