React - 如何在 Array map 函数结束之前显示骨架占位符

React - How to show skeleton placeholders until Array map function ended

我有一个国家/地区列表组件,其中包含国家/地区 phone 代码、国家/地区名称及其使用 map() 函数的国旗,因此加载时间有点长。如果 map() 函数结束或仍在工作,我需要获取信息,然后使用它来显示然后隐藏占位符。我怎样才能做到这一点?

我无法在 Internet 上找到合适的解决方案或无法使用它们。就像在 React 组件中使用 Promise(all) 一样,我一直很难弄清楚语法应该如何。

<CountryList />分量:

// Packages I used for countries
import { getCountries, getCountryCallingCode } from "react-phone-number-input"
import countryNames from "react-phone-number-input/locale/en.json"
import ReactCountryFlag from "react-country-flag"

// The array comes from package
const countries = getCountries()

<CountryList>
  {countries.map((country) => (
    <CountryItem key={country} value={country}>
      <ReactCountryFlag countryCode={country} svg />
      <span>
        {countryNames[country]}
        <span>+{getCountryCallingCode(country)}</span>
      </span>
    </CountryItem>
  ))}
</CountryList>

<CountryItemSkeleton />分量:

// The package I used for skeleton placeholder
import ContentLoader from "react-content-loader"

<CountryItemSkeleton>
  <CountryItem>
    <ContentLoader>
      <rect x="0" y="0" rx="3" ry="3" width="40" height="30" />
      <rect x="52" y="8" rx="7" ry="7" width="248" height="14" />
    </ContentLoader>
  </CountryItem>
  <CountryItem>
    <ContentLoader>
      <rect x="0" y="0" rx="3" ry="3" width="40" height="30" />
      <rect x="52" y="8" rx="7" ry="7" width="248" height="14" />
    </ContentLoader>
  </CountryItem>
  <CountryItem>
    <ContentLoader>
      <rect x="0" y="0" rx="3" ry="3" width="40" height="30" />
      <rect x="52" y="8" rx="7" ry="7" width="248" height="14" />
    </ContentLoader>
  </CountryItem>
</CountryItemSkeleton>

这里的一切都是同步的,因此您不能等待或监视 map() 进度。

您可以尝试在效果挂钩中加载国家/地区列表,以便在安装组件后填充它。在初始渲染中,您可以使用 骨架 组件

const [countries, setCountries] = useState([]);

// run once on mount
useEffect(() => {
  setCountries(getCountries());
}, []);

// or even with a small delay
useEffect(() => {
  const timer = setTimeout(setCountries, 200, getCountries());
  return () => {
    clearTimeout(timerId);
  };
}, []);

return countries.length === 0 ? (
  <CountryItemSkeleton />
) : (
  <CountryList>
    {countries.map((country) => (
      <CountryItem key={country} value={country}>
        {/* etc */}
      </CountryItem>
    ))}
  </CountryList>
);