Частичное обновление компонента при обновлении каждые 6 секунд - PullRequest
0 голосов
/ 18 марта 2020

У меня есть компонент, который отображает некоторый статус (я получаю его с помощью конечной точки GET и сохраняю его в состоянии с именем statusRows.)

export const Status = (props) => {
    const classes = useStyles();
    const [statusRows, setStatusRows] = useState([])
    const [sortType, setSortType] = useState('submitted_on') // or 'run' or 'success'
    const [sortOrder, setSortOrder] = useState('desc') // or asc

У меня есть состояния, как указано выше.

Функция, которую я использую для извлечения статуса из API, выглядит следующим образом:

const getInstallStatus = () => {
        let options = {
            headers: header,
            method: 'get',
            mode: 'cors',
        }
        const urls = [GET_ENDPOINT];
        const fetchJson = url => fetch(url, options).then(res => res.json());
        Promise.all(urls.map(fetchJson))
            .then(([status]) => {
                setStatusRows(status)
            })
            .catch(err => {
                console.log(err)
            });
        const rows = [];
        rows.forEach((item) => {
            rows.push(createTableData(item.profile, ... // hidden))
        })
        setStatusRows(rows)
    }
    useEffect(() => {
        getInstallStatus()
    }, []);

Как видите, я переформатирую ответ на данные таблицы и сохраняю в statusRows. Я использую это состояние для рендеринга этих данных в табличном формате.

Это отображается один раз при загрузке компонента, так как он использует useEffect с [].

У меня также есть другой useEffect с интервалами для обновления каждые 6 секунд.

useEffect(() => {
    const interval = setInterval(() => {
        // setSec(sec => sec + 1);
        let options = {
            headers: header,
            method: 'get',
            mode: 'cors',
        }
        const urls = [GET_ENDPOINT];
        const fetchJson = url => fetch(url, options).then(res => res.json());
        Promise.all(urls.map(fetchJson))
            .then(([status]) => {
                let sortedArr = status
                sortedArr.sort(function (a, b) {
                    var keyA = new Date(a.submitted_on),
                        keyB = new Date(b.submitted_on);
                    // Compare the 2 dates
                    if (keyA < keyB) return 1;
                    if (keyA > keyB) return -1;
                    return 0;
                });
                setStatusRows(sortedArr)
            })
            .catch(err => {
                console.log(err)
            });
        const rows = [];
        statusRows.forEach((item) => {
            rows.push(createTableData(item....))
        })
        setStatusRows(rows)
    }, 6000);
    return () => clearInterval(interval);
}, []);

Таким образом, это технически повторно вызывает конечную точку GET каждые 6 секунд, чтобы отобразить актуальный результат состояния. Однако всякий раз, когда он обновляется, таблица на секунду опорожняется, поскольку данные таблицы находятся в процессе повторного заполнения.

Есть ли способ сделать обновление более плавным? Я не хочу делать состояние пустым во время обновления. Я просто хочу, чтобы он обновлялся плавно. e.g. Current [Old] --> [] --> [New], Intended: [Old] --> [New]

Любая помощь, пожалуйста?

Редактировать

const createTableData = (profile, run_on_devices, submitted, testcase, status, success_status, jenkins_log_url) => {
    return { profile, run_on_devices, submitted, testcase, status, success_status, jenkins_log_url };
}

1 Ответ

1 голос
/ 18 марта 2020

Для начала вы используете Promise.all, который выполняется асинхронно, затем сразу после этого блока вы устанавливаете состояние в пустой массив, который очищает ваши данные. Я верю, что вы можете просто установить состояние в .hen, и все будут счастливы.

useEffect(() => {
    const interval = setInterval(() => {
        // setSec(sec => sec + 1);
        let options = {
            headers: header,
            method: 'get',
            mode: 'cors',
        }
        const urls = [GET_ENDPOINT];
        const fetchJson = url => fetch(url, options).then(res => res.json());
        Promise.all(urls.map(fetchJson))
            .then(([status]) => {
                let sortedArr = status
                sortedArr.sort(function (a, b) {
                    var keyA = new Date(a.submitted_on),
                        keyB = new Date(b.submitted_on);
                    // Compare the 2 dates
                    if (keyA < keyB) return 1;
                    if (keyA > keyB) return -1;
                    return 0;
                });
                const temp = sortedArr.map(createTableData)
                setStatusRows(temp)
            })
            .catch(err => {
                console.log(err)
            });
    }, 6000);
    return () => clearInterval(interval);
}, []);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...