[0,1,2,3] .map工作正常,array.map提供了奇怪的结果 [英] [0,1,2,3].map works fine, array.map gives strange results

查看:83
本文介绍了[0,1,2,3] .map工作正常,array.map提供了奇怪的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用成帧器运动,并且我试图实现交错,以便每个下一个孩子都有一些不错的延迟.有一条关键的代码行,其中当我用recipes.map替换[0, 1, 2, 3].map时,突然所有子级都被视为一个巨大的块,并且它们不会错开.

只需查看此演示,您肯定会明白我的意思.此代码有什么问题?我迷失了方向:)

function App() {
  const request = `https://www.themealdb.com/api/json/v1/1/search.php?s=chicken`;
  const [recipes, setRecipes] = useState([]);

  useEffect(() => {
    getRecipes();
  }, []);

  const getRecipes = async () => {
    const response = await fetch(request);
    const data = await response.json();
    setRecipes(data.meals);
    console.log(data.meals);
  };

  const container = {
    hidden: { opacity: 1, scale: 0 },
    visible: {
      opacity: 1,
      scale: 1,
      transition: {
        when: "beforeChildren",
        staggerChildren: 0.5
      }
    }
  };

  const item = {
    hidden: { x: 100, opacity: 0 },
    visible: {
      x: 0,
      opacity: 1
    }
  };

  return (
    <div className="App">
      <motion.ul variants={container} initial="hidden" animate="visible">
        {[0, 1, 2, 3].map(recipe => (
          <motion.li key={recipe.idMeal} variants={item}>
            <RecipeCard title={recipe.strMeal} />
          </motion.li>
        ))}
      </motion.ul>
      <motion.ul variants={container} initial="hidden" animate="visible">
        {recipes.map(recipe => (
          <motion.li key={recipe.idMeal} variants={item}>
            <RecipeCard title={recipe.strMeal} />
          </motion.li>
        ))}
      </motion.ul>
    </div>
  );
}

有点棘手,但只有在可用时才需要设置动画:

animate={recipes.length > 0 && "visible"}

那是因为您实际上是在第一个渲染中为一个空数组制作动画.

animate="visible"

然后,在异步调用之后更新recipes时,您不会再次触发动画.

const container = {
  hidden: { opacity: 1, scale: 0 },
  visible: {
    opacity: 1,
    scale: 1,
    transition: {
      staggerChildren: 0.5
    }
  }
};

const item = {
  hidden: { x: 100, opacity: 0 },
  visible: {
    x: 0,
    opacity: 1
  }
};

const request = `https://www.themealdb.com/api/json/v1/1/search.php?s=chicken`;

function App() {
  const [recipes, setRecipes] = useState([]);

  useEffect(() => {
    const getRecipes = async () => {
      const response = await fetch(request);
      const data = await response.json();
      setRecipes(data.meals);
      console.log(data.meals);
    };
    getRecipes();
  }, []);

  return (
    <div className="App">
      <motion.ul
        variants={container}
        initial="hidden"
        animate={recipes.length > 0 && "visible"}
      >
        {recipes.map(recipe => (
          <motion.li key={recipe.idMeal} variants={item}>
            <RecipeCard title={recipe.strMeal} />
          </motion.li>
        ))}
      </motion.ul>
    </div>
  );
}

I am using framer motion and I am trying to achieve stagger so that every next child has some nice delay. There is one crucial line of code in which when I replace [0, 1, 2, 3].map with recipes.map suddenly all of the children are treated as one huge block and they do not stagger.

Just check out this demo and you will surely know what I mean. What is wrong with this code? I am losing my mind :)

function App() {
  const request = `https://www.themealdb.com/api/json/v1/1/search.php?s=chicken`;
  const [recipes, setRecipes] = useState([]);

  useEffect(() => {
    getRecipes();
  }, []);

  const getRecipes = async () => {
    const response = await fetch(request);
    const data = await response.json();
    setRecipes(data.meals);
    console.log(data.meals);
  };

  const container = {
    hidden: { opacity: 1, scale: 0 },
    visible: {
      opacity: 1,
      scale: 1,
      transition: {
        when: "beforeChildren",
        staggerChildren: 0.5
      }
    }
  };

  const item = {
    hidden: { x: 100, opacity: 0 },
    visible: {
      x: 0,
      opacity: 1
    }
  };

  return (
    <div className="App">
      <motion.ul variants={container} initial="hidden" animate="visible">
        {[0, 1, 2, 3].map(recipe => (
          <motion.li key={recipe.idMeal} variants={item}>
            <RecipeCard title={recipe.strMeal} />
          </motion.li>
        ))}
      </motion.ul>
      <motion.ul variants={container} initial="hidden" animate="visible">
        {recipes.map(recipe => (
          <motion.li key={recipe.idMeal} variants={item}>
            <RecipeCard title={recipe.strMeal} />
          </motion.li>
        ))}
      </motion.ul>
    </div>
  );
}

解决方案

Its a bit tricky, but you need to animate only when the items are available:

animate={recipes.length > 0 && "visible"}

That's because on the first render you actually animate an empty array.

animate="visible"

Then, when you update the recipes after the async call, you don't trigger the animation again.

const container = {
  hidden: { opacity: 1, scale: 0 },
  visible: {
    opacity: 1,
    scale: 1,
    transition: {
      staggerChildren: 0.5
    }
  }
};

const item = {
  hidden: { x: 100, opacity: 0 },
  visible: {
    x: 0,
    opacity: 1
  }
};

const request = `https://www.themealdb.com/api/json/v1/1/search.php?s=chicken`;

function App() {
  const [recipes, setRecipes] = useState([]);

  useEffect(() => {
    const getRecipes = async () => {
      const response = await fetch(request);
      const data = await response.json();
      setRecipes(data.meals);
      console.log(data.meals);
    };
    getRecipes();
  }, []);

  return (
    <div className="App">
      <motion.ul
        variants={container}
        initial="hidden"
        animate={recipes.length > 0 && "visible"}
      >
        {recipes.map(recipe => (
          <motion.li key={recipe.idMeal} variants={item}>
            <RecipeCard title={recipe.strMeal} />
          </motion.li>
        ))}
      </motion.ul>
    </div>
  );
}

这篇关于[0,1,2,3] .map工作正常,array.map提供了奇怪的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆