React js обновляет функциональный компонент после получения всех данных

Я использую функциональный компонент реакции и получаю внешние данные внутри цикла for. Проблема в том, что компонент обновляется бесконечно. Ниже показано, что я пытаюсь сделать:

const SongGrid = (props: any) => {
 const [songData, setSongData] = useState(props.location.state.items);
 useEffect(() => {
    const fetchData = (data: any) => {
     CommonService.postApiExecutor('getdata', {data.id})
     .then((response) => { 
        element.extProp1 = response.data.one;
        setSongData(
        songData.map((item: any) =>
          item.song_id === song.song_id
            ? { ...item, extProp1 : extProp1 }
            : item,
        ),
      );
      })
    }
    songDataObj.forEach((element: any) => {
      fetchData(element)
    })
 },[songData])
 return (
  <div>
   <table>
     <thead><th>Song Name</th><th>Ext property 1</th></thead>
     <tbody>
      {songDataObj.map((song: any, i: any) => (
       <tr>
        <td>song.songName</td>
        <td>{song.extProp1?song.extProp1:''}</td>
       </tr>
      ))}
     </tbody>
   </table>
 </div>
 )
}

Я обновляю songData при каждом ответе, и ячейки таблицы обновляются не менее 70, 80 раз и страница сбой.


person DIPESH NAYAK    schedule 16.04.2020    source источник


Ответы (3)


когда вы хотите сделать что-то вроде componentDidMount, вам нужно добавить это

useEffect(()=>{ [you code here] },[]) <---- you forgot the brackets

если в скобках ничего нет, код, находящийся внутри useEffect, будет запущен только один раз.

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

person Cyrus Zei    schedule 16.04.2020

используйте это useEffect(() => ,[]) вместо useEffect(() => )

проблема в том, что вы вызываете setState внутри useEffect, и каждый раз, когда происходит повторный рендеринг, он вызывает повторный запуск useEffect, снова вызывает setState, снова вызывает useEffect и снова вызывает setState и ........... это продолжается вечно. поэтому, чтобы ограничить это, вы должны поместить [dependency] в конец вашего хука useEffect. для управления триггером вызова useEffect или вы можете управлять им, поместив предложение If внутри useEffect, чтобы не запускать сетевой вызов снова.

person TheEhsanSarshar    schedule 16.04.2020
comment
Я пробовал useEffect (() = ›, []), но проблема в том, что компонент не обновляется, когда возвращается ответ api. а в таблице хранятся старые значения. - person DIPESH NAYAK; 16.04.2020

Проблема заключается в использовании setState внутри useEffect. Он будет запускаться каждый раз при изменении состояния, при этом сам меняет состояние. Вы можете определить зависимость в useEffect функции, чтобы предотвратить ее бесконечный повторный запуск.

useEffect(()=>{} ,[])

Добавление пустого массива в качестве второго параметра в useEffect означает, что он будет запускаться только один раз при монтировании компонента.

person Makan    schedule 16.04.2020