Реагирует на слишком много изменений с помощью useState

javascript #reactjs #rendering #use-state

#javascript #reactjs #рендеринг #use-state

Вопрос:

Мой код :

 import Item from './Item_att.js';
import axios from 'axios';

const Attraction_list = () => {
...
const [maindata, setMainData] = useState([]); //setData
const [postsPerPage] = useState(6);
...

let attList = async (areaCode, cityCode) => { //approach openAPI
    const url = `...`;
    try {
        const {data: res} = await axios.get(url)
        const list = res.response.body.items.item;

        console.log("rendering!")
        setMainData(list);
    } catch (err) {
        console.log(err);
    }
}

...

attList(1, 1).then(data => {console.log("then");}) //make maindata
const currentPosts = (tmp) => {    //slice data
    return tmp.slice(indexOfFirst, indexOfLast);
}

...

return (
    <div>
        ...
        <Item rlist={currentPosts(maindata)} moveTo={moveTo} area={area} city={"강남"}></Item>
    </div>
);
};

export default Attraction_list;
 

Функция attList извлекает данные из OpenAPI.
Функция currentPosts выполняется при Item рендеринге компонента, она возвращает нарезанный список.

Я думаю, что они выполнялись только один раз,

Результат: слишком много повторной рендеринга в этой программе. Функция attList и функция currentPost выполняются слишком много раз. Я не знаю почему.

Зачем так много повторной рендеринга?

Ответ №1:

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

 React.useEffect(()=>{

    attList(1, 1)

},[])
 

Ответ №2:

Когда вы вызываете

 setMainData(list);
 

внутри вашей функции attList react повторно отобразит ваш компонент при изменении состояния. Затем ваша функция attList снова запустится, что и вызывает цикл.

Чтобы предотвратить такое поведение, вы можете использовать хук реакции useEffect для вызова функции attList один раз при первом рендеринге и только при первом рендеринге.

https://reactjs.org/docs/hooks-effect.html

Ответ №3:

Вы создали бесконечный цикл, потому attList что будет выполняться setMainData , который затем повторно отобразит компонент и для attList этого снова выполнит его.

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