最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Loop through a state array in React and switch each item to true using setTimeout - Stack Overflow

programmeradmin1浏览0评论

I have an array in state:

const [show, setShow] = useState([false, false, false, false])

These affect whether or not an image is displayed.

I'd like to iterate through them one by one, using a delay of 500ms between each iteration, and switch each to true so that the images are slowly revealed. To be clear, they should all end up as true, rather than just being temporarily switched to true.

I've used lots of methods so far, but can only get them to change the current index to true during that loop iteration.

Any help would be appreciated!

UPDATE: here's where I'm currently up to. It's not working well!


export const Leaves = ({ svgHeight }) => {
  const [show, setShow] = useState(0);

  let inc = show;
  setInterval(() => {
    setShow(inc);
    inc++;
  }, 1000);
  console.log(show);
  return (
    <svg
      className={`leaves ${svgHeight}`}
      style={{ height: svgHeight }}
      clip-rule="evenodd"
      fill-rule="evenodd"
      stroke-linejoin="round"
      stroke-miterlimit="2"
      version="1.1"
      viewBox="0 0 2e3 3e3"
      xmlSpace="preserve"
      xmlns=";
    >
      <g fill-rule="nonzero">
        <rect width="2e3" height="" fill="rgba(255,255,255,0)" />
        {show >= 0 && (
          <path
            d="m1403.3 1640.2c0.15-6.25-10-2.02-10.12 2.96-6.34 252.73-159.68 479.21-212.39 724.37-4.63 21.55-8.4 43.21-11.19 64.95 0.01-12.74-0.11-25.47-0.52-38.21-2.63-82.46-14.27-164.49-34.1-245.25-19.63-79.96-45.93-158.57-70.15-237.59-14.33-46.76-27.92-93.78-38.87-141.22-10.09-46.61-15.93-79.22-19.45-108.26-9.685-79.88-7.238-160.44 1.9-240.27 17.87-156.05 60.33-309 89.75-463.57 31.83-167.18 47.55-338.89-3.43-504.59-1.73-5.651-11.01 0.396-9.55 5.151 93.74 304.73-36.96 614.26-80.68 916.56-10.753 74.37-16.742 149.42-13.447 224.36 2.014 45.81 8.113 91.25 16.947 136.35-9.784-8.67-20.36-16.82-31.166-24.54-46.083-32.94-93.535-62.48-133.06-101.53-79.124-78.17-130.84-175.86-148.35-277.67-9.992-58.09-8.543-117.1 4.538-174.75 1.468-6.47-8.832-4.68-10.024 0.57-44.768 197.31 48.905 406.26 234.46 530.73 29.025 19.47 62.557 39.93 87.232 64.93 5.68 26.79 12.25 53.47 19.47 80.02 44.02 161.74 106.27 319.25 122.77 485.57 18.48 186.16-8.54 374.76-78.52 551.89-2.47 6.24 7.05 7.47 9.26 1.88 42.47-107.51 69.29-219.14 79.87-331.99 7.18-84.43 19.51-165.14 49.02-258.38 35.69-112.75 93.36-244.89 156.52-437.84 21.8-66.57 31.55-135.49 33.29-204.63z"
            fill="#778680"
          />
        )}
        {show >= 1 && (
          <path
            d="m722.11 1713.1s64.149 145.58 341.52 217.54c0 0-41.09-77.82-154.61-154.63-50.879-34.43-186.91-62.91-186.91-62.91z"
            fill="#778680"
          />
        )}
        {show >= 2 && (
          <path
            d="m1528.1 1897.3s-178.19 45.87-283.64 283.62c0 0 136.08-77.2 235.73-171.17 44.66-42.11 47.91-112.45 47.91-112.45z"
            fill="#778680"
          />
        )}
        {show >= 3 && (
          <path
            d="m893.99 1155.4s-144.93 99.01-137.52 352.89c0 0 92.023-114.73 142.85-233.44 22.78-53.2-5.328-119.45-5.328-119.45z"
            fill="#778680"
          />
        )}
        {show >= 4 && (
          <path
            d="m993.38 1625.2s104.42-133.73 128.54-217.4 26.61-187.11 26.61-187.11-82.26 90.13-112.03 186.81-43.122 217.7-43.122 217.7z"
            fill="#707f79"
          />
        )}
        {show >= 5 && (
          <path
            d="m993.35 1624.8s220.77-112.98 217.52-269.43c0 0-191.55 144.86-217.52 269.43z"
            fill="#778680"
          />
        )}
        {show >= 6 && (
          <path
            d="m1111.1 864.03s247.11-161.1 214.13-340.84c0 0-205.72 193.71-214.13 340.84z"
            fill="#778680"
          />
        )}
        {show >= 7 && (
          <path
            d="m1384.7 1774.1s141.56-162.2 72.78-288.36c0 0-103.08 178.8-72.78 288.36z"
            fill="#778680"
          />
        )}
        {show >= 8 && (
          <path
            d="m686.39 1191.8s139.32-163.58 68.809-289.05c0 0-100.6 179.8-68.809 289.05z"
            fill="#778680"
          />
        )}
        {show >= 9 && (
          <path
            d="m1112.9 549.99s50.57-245.4-107.74-352.63c0 0 2.79 245.74 107.74 352.63z"
            fill="#778680"
          />
        )}
        {show >= 10 && (
          <path
            d="m1322.8 1978.1s-177.71-216.97-81.85-379.77c0 0 126.58 237.41 81.85 379.77z"
            fill="#778680"
          />
        )}
        {show >= 11 && (
          <path
            d="m711.15 1421.6s-246.84-130.51-239.05-305.33c0 0 212.94 165.58 239.05 305.33z"
            fill="#778680"
          />
        )}
        {show >= 12 && (
          <path
            d="m1085 1006.8s2.36-91.018-58.05-186.86c-60.4-95.848-182.08-258.17-182.08-258.17s6.079 140.83 29.088 200.85c44.983 117.34 203.48 197.77 211.04 244.19z"
            fill="#778680"
          />
        )}
      </g>
    </svg>
  );
};

I have an array in state:

const [show, setShow] = useState([false, false, false, false])

These affect whether or not an image is displayed.

I'd like to iterate through them one by one, using a delay of 500ms between each iteration, and switch each to true so that the images are slowly revealed. To be clear, they should all end up as true, rather than just being temporarily switched to true.

I've used lots of methods so far, but can only get them to change the current index to true during that loop iteration.

Any help would be appreciated!

UPDATE: here's where I'm currently up to. It's not working well!


export const Leaves = ({ svgHeight }) => {
  const [show, setShow] = useState(0);

  let inc = show;
  setInterval(() => {
    setShow(inc);
    inc++;
  }, 1000);
  console.log(show);
  return (
    <svg
      className={`leaves ${svgHeight}`}
      style={{ height: svgHeight }}
      clip-rule="evenodd"
      fill-rule="evenodd"
      stroke-linejoin="round"
      stroke-miterlimit="2"
      version="1.1"
      viewBox="0 0 2e3 3e3"
      xmlSpace="preserve"
      xmlns="http://www.w3./2000/svg"
    >
      <g fill-rule="nonzero">
        <rect width="2e3" height="" fill="rgba(255,255,255,0)" />
        {show >= 0 && (
          <path
            d="m1403.3 1640.2c0.15-6.25-10-2.02-10.12 2.96-6.34 252.73-159.68 479.21-212.39 724.37-4.63 21.55-8.4 43.21-11.19 64.95 0.01-12.74-0.11-25.47-0.52-38.21-2.63-82.46-14.27-164.49-34.1-245.25-19.63-79.96-45.93-158.57-70.15-237.59-14.33-46.76-27.92-93.78-38.87-141.22-10.09-46.61-15.93-79.22-19.45-108.26-9.685-79.88-7.238-160.44 1.9-240.27 17.87-156.05 60.33-309 89.75-463.57 31.83-167.18 47.55-338.89-3.43-504.59-1.73-5.651-11.01 0.396-9.55 5.151 93.74 304.73-36.96 614.26-80.68 916.56-10.753 74.37-16.742 149.42-13.447 224.36 2.014 45.81 8.113 91.25 16.947 136.35-9.784-8.67-20.36-16.82-31.166-24.54-46.083-32.94-93.535-62.48-133.06-101.53-79.124-78.17-130.84-175.86-148.35-277.67-9.992-58.09-8.543-117.1 4.538-174.75 1.468-6.47-8.832-4.68-10.024 0.57-44.768 197.31 48.905 406.26 234.46 530.73 29.025 19.47 62.557 39.93 87.232 64.93 5.68 26.79 12.25 53.47 19.47 80.02 44.02 161.74 106.27 319.25 122.77 485.57 18.48 186.16-8.54 374.76-78.52 551.89-2.47 6.24 7.05 7.47 9.26 1.88 42.47-107.51 69.29-219.14 79.87-331.99 7.18-84.43 19.51-165.14 49.02-258.38 35.69-112.75 93.36-244.89 156.52-437.84 21.8-66.57 31.55-135.49 33.29-204.63z"
            fill="#778680"
          />
        )}
        {show >= 1 && (
          <path
            d="m722.11 1713.1s64.149 145.58 341.52 217.54c0 0-41.09-77.82-154.61-154.63-50.879-34.43-186.91-62.91-186.91-62.91z"
            fill="#778680"
          />
        )}
        {show >= 2 && (
          <path
            d="m1528.1 1897.3s-178.19 45.87-283.64 283.62c0 0 136.08-77.2 235.73-171.17 44.66-42.11 47.91-112.45 47.91-112.45z"
            fill="#778680"
          />
        )}
        {show >= 3 && (
          <path
            d="m893.99 1155.4s-144.93 99.01-137.52 352.89c0 0 92.023-114.73 142.85-233.44 22.78-53.2-5.328-119.45-5.328-119.45z"
            fill="#778680"
          />
        )}
        {show >= 4 && (
          <path
            d="m993.38 1625.2s104.42-133.73 128.54-217.4 26.61-187.11 26.61-187.11-82.26 90.13-112.03 186.81-43.122 217.7-43.122 217.7z"
            fill="#707f79"
          />
        )}
        {show >= 5 && (
          <path
            d="m993.35 1624.8s220.77-112.98 217.52-269.43c0 0-191.55 144.86-217.52 269.43z"
            fill="#778680"
          />
        )}
        {show >= 6 && (
          <path
            d="m1111.1 864.03s247.11-161.1 214.13-340.84c0 0-205.72 193.71-214.13 340.84z"
            fill="#778680"
          />
        )}
        {show >= 7 && (
          <path
            d="m1384.7 1774.1s141.56-162.2 72.78-288.36c0 0-103.08 178.8-72.78 288.36z"
            fill="#778680"
          />
        )}
        {show >= 8 && (
          <path
            d="m686.39 1191.8s139.32-163.58 68.809-289.05c0 0-100.6 179.8-68.809 289.05z"
            fill="#778680"
          />
        )}
        {show >= 9 && (
          <path
            d="m1112.9 549.99s50.57-245.4-107.74-352.63c0 0 2.79 245.74 107.74 352.63z"
            fill="#778680"
          />
        )}
        {show >= 10 && (
          <path
            d="m1322.8 1978.1s-177.71-216.97-81.85-379.77c0 0 126.58 237.41 81.85 379.77z"
            fill="#778680"
          />
        )}
        {show >= 11 && (
          <path
            d="m711.15 1421.6s-246.84-130.51-239.05-305.33c0 0 212.94 165.58 239.05 305.33z"
            fill="#778680"
          />
        )}
        {show >= 12 && (
          <path
            d="m1085 1006.8s2.36-91.018-58.05-186.86c-60.4-95.848-182.08-258.17-182.08-258.17s6.079 140.83 29.088 200.85c44.983 117.34 203.48 197.77 211.04 244.19z"
            fill="#778680"
          />
        )}
      </g>
    </svg>
  );
};
Share Improve this question edited Feb 4 at 12:04 Maccles asked Feb 4 at 11:37 MacclesMaccles 1319 bronze badges 4
  • 3 It's not really possible to tell what you're doing wrong without seeing the code. That said a much easier solution would be to use a number instead, increment it, and use it to check if an image should be displayed (if image index < the number, show the image) – Guy Incognito Commented Feb 4 at 11:40
  • that's a good call! Annoyingly I've been through so many attempts that the code in front of me now if pretty meaningless, so it wouldn't help to share it. Thank you – Maccles Commented Feb 4 at 11:44
  • 1 Why just not use useEffect have setInterval inside it and change state setShow((prevState) => ... do what you need based on previous state on each interval tick – MePo Commented Feb 4 at 12:23
  • I would try setTimeout(() => setShow(old => old + 1), 1000); instead of the setInterval. Whenever it calls setShow it will re-render, and whenever it re-renders it will create a new timeout, so it increments without directly using a loop. – James Commented Feb 4 at 13:50
Add a comment  | 

2 Answers 2

Reset to default 0

Please see a sample code below.

Coding highlights:

a. The component path must be rendered as a list.

b. On each render, this list must be incrementing by one item.

c. When all d properties are rendered, then the rendering is restarted.

d. The state change must be coded in useEffect with a delay of 1 second.

App.js

import { useEffect, useState } from 'react';

export default function App() {
  return (
    <>
      <Leaves svgHeight={500} />
    </>
  );
}

const Leaves = ({ svgHeight }) => {
  const [show, setShow] = useState('');

  useEffect(() => {
    let inc = 0;

    let timer = setInterval(() => {
      let incSnapshot = inc;
      setShow(incSnapshot);
      inc++;

      if (inc === 12) {
        inc = 0;
      }
    }, 1000);

    return () => clearInterval(timer);
  }, []);

  return (
    <svg
      className={`leaves ${svgHeight}`}
      style={{ height: svgHeight }}
      clip-rule="evenodd"
      fill-rule="evenodd"
      stroke-linejoin="round"
      stroke-miterlimit="2"
      version="1.1"
      viewBox="0 0 2e3 3e3"
      xmlSpace="preserve"
      xmlns="http://www.w3./2000/svg"
    >
      <g fill-rule="nonzero">
        <rect width="2e3" height="" fill="rgba(255,255,255,0)" />
        {d.slice(0, show).map((i, index) => (
          <path d={i} fill="#778680" key={index} />
        ))}
      </g>
    </svg>
  );
};

const d = [
  'm1403.3 1640.2c0.15-6.25-10-2.02-10.12 2.96-6.34 252.73-159.68 479.21-212.39 724.37-4.63 21.55-8.4 43.21-11.19 64.95 0.01-12.74-0.11-25.47-0.52-38.21-2.63-82.46-14.27-164.49-34.1-245.25-19.63-79.96-45.93-158.57-70.15-237.59-14.33-46.76-27.92-93.78-38.87-141.22-10.09-46.61-15.93-79.22-19.45-108.26-9.685-79.88-7.238-160.44 1.9-240.27 17.87-156.05 60.33-309 89.75-463.57 31.83-167.18 47.55-338.89-3.43-504.59-1.73-5.651-11.01 0.396-9.55 5.151 93.74 304.73-36.96 614.26-80.68 916.56-10.753 74.37-16.742 149.42-13.447 224.36 2.014 45.81 8.113 91.25 16.947 136.35-9.784-8.67-20.36-16.82-31.166-24.54-46.083-32.94-93.535-62.48-133.06-101.53-79.124-78.17-130.84-175.86-148.35-277.67-9.992-58.09-8.543-117.1 4.538-174.75 1.468-6.47-8.832-4.68-10.024 0.57-44.768 197.31 48.905 406.26 234.46 530.73 29.025 19.47 62.557 39.93 87.232 64.93 5.68 26.79 12.25 53.47 19.47 80.02 44.02 161.74 106.27 319.25 122.77 485.57 18.48 186.16-8.54 374.76-78.52 551.89-2.47 6.24 7.05 7.47 9.26 1.88 42.47-107.51 69.29-219.14 79.87-331.99 7.18-84.43 19.51-165.14 49.02-258.38 35.69-112.75 93.36-244.89 156.52-437.84 21.8-66.57 31.55-135.49 33.29-204.63z',
  'm722.11 1713.1s64.149 145.58 341.52 217.54c0 0-41.09-77.82-154.61-154.63-50.879-34.43-186.91-62.91-186.91-62.91z',
  'm1528.1 1897.3s-178.19 45.87-283.64 283.62c0 0 136.08-77.2 235.73-171.17 44.66-42.11 47.91-112.45 47.91-112.45z',
  'm893.99 1155.4s-144.93 99.01-137.52 352.89c0 0 92.023-114.73 142.85-233.44 22.78-53.2-5.328-119.45-5.328-119.45z',
  'm993.38 1625.2s104.42-133.73 128.54-217.4 26.61-187.11 26.61-187.11-82.26 90.13-112.03 186.81-43.122 217.7-43.122 217.7z',
  'm993.35 1624.8s220.77-112.98 217.52-269.43c0 0-191.55 144.86-217.52 269.43z',
  'm1111.1 864.03s247.11-161.1 214.13-340.84c0 0-205.72 193.71-214.13 340.84z',
  'm1384.7 1774.1s141.56-162.2 72.78-288.36c0 0-103.08 178.8-72.78 288.36z',
  'm686.39 1191.8s139.32-163.58 68.809-289.05c0 0-100.6 179.8-68.809 289.05z',
  'm1112.9 549.99s50.57-245.4-107.74-352.63c0 0 2.79 245.74 107.74 352.63z',
  'm1322.8 1978.1s-177.71-216.97-81.85-379.77c0 0 126.58 237.41 81.85 379.77z',
  'm711.15 1421.6s-246.84-130.51-239.05-305.33c0 0 212.94 165.58 239.05 305.33z',
  'm1085 1006.8s2.36-91.018-58.05-186.86c-60.4-95.848-182.08-258.17-182.08-258.17s6.079 140.83 29.088 200.85c44.983 117.34 203.48 197.77 211.04 244.19z',
];

Output:

On load of the app:

After a second:

After 12 seconds

Sometimes CSS animation can solve the problem. It's lighter and easy to use, plus there's no need to add code (just 1 or two classes to the items). So you can render all your Items once (hidden by default or with its specific class). Add to any items a dinamic class to change the delay value. If you type "css animation to show items slowly" on ChatGPT site you will see a clear example.

发布评论

评论列表(0)

  1. 暂无评论