Как не читать свойство объект до его получения

Есть react-компонент:

import React, { useState, useEffect } from 'react';
import { useHttp } from '../../hooks/http.hooks';

function Main() {
    const { loading, error, request } = useHttp(); // Для запросов
    const [news, setNews] = useState([]);

    useEffect(async() => {
        takeNews(4)
    }, []);

    async function takeNews(quantity = 5) {
        const data = await request(`http://localhost:5500/api/news/top/${quantity}`); // Получаю массив из 4 объектов
        if (Array.isArray(data.news)) {
            setNews(data.news);
        }
    }

    return (
        <>
            {news[0].content.headline}
        </>
    );
}

export default Main;

При первом рендере news[0].content.headline выдаст ошибку:

Нельзя прочитать свойство из undefined.

Как можно игнорировать избежать этого? Единственное решение, которое я придумал, это расфасовать news на дочерние объекты, а потом сделать с ними тоже самое, но тогда в коде будет очень много неоправданных переменных и он будет некрасивым.


Ответы (2 шт):

Автор решения: Илья Паймушкин

Можно это сделать несколькими способами (при условии что в вашем кастомном эта переменная изменяется):

if (loading) return <div>Loading...</div>
return (
    <>
       {news[0].content.headline}
    </>
);

Можно воспользоваться например функцией get из lodash

return (
        <>
            {get(news, "[0].content.headline", "No Data")}
            
        </>
    );

Можно проверить длину массива:

if (news.length === 0) return "No Data";
return (
        <>
            {news[0].content.headline}
            
        </>
    );
→ Ссылка
Автор решения: Voprositel

Можно также использовать опциональный оператор:

const obj = {}

console.log(obj?.a?.b) // undefined
console.log(obj.a.b) // error

Пока оператор не сильно хорошо поддерживается и в некоторых браузерах может возникнуть SyntaxError, поэтому можно использовать сравнение через &&:

const obj = {}

console.log(obj.a && obj.a.b) // undefined

→ Ссылка