const url = props.url; const render = props.render; const fallback = props.fallback; State.init({ data: null, isFetched: false, }); const Loader = styled.svg` animation: rotate 2s linear infinite; margin: -25px 0 0 -25px; width: 50px; height: 50px; & .path { stroke: #5652bf; stroke-linecap: round; animation: dash 1.5s ease-in-out infinite; } @keyframes rotate { 100% { transform: rotate(360deg); } } @keyframes dash { 0% { stroke-dasharray: 1, 150; stroke-dashoffset: 0; } 50% { stroke-dasharray: 90, 150; stroke-dashoffset: -35; } 100% { stroke-dasharray: 90, 150; stroke-dashoffset: -124; } } `; const spinner = ( <Loader viewBox="0 0 50 50"> <circle className="path" cx="25" cy="25" r="20" fill="none" strokeWidth="4" /> </Loader> ); if (!state.isFetched) { asyncFetch(url).then(({ body }) => { State.update({ data: body, isFetched: true }); }); return fallback ? fallback(spinner) : spinner; } return render(state.data);