为什么将 React Context 与 Framer Motion 一起使用不起作用?
Why does using React Context with Framer Motion not work?
我有一个状态存储在本地的幻灯片版本,您可以看到幻灯片效果很好,只有在动画完成后才会卸载幻灯片组件。 https://stackblitz.com/edit/react-framer-motion-slideshow-official?file=src%2FSlideShow.js
一旦我添加了上下文来处理这些值,动画滑动仍然有效,但是当动画开始时,现有的组件被新的幻灯片内容替换,这看起来很奇怪。此外,幻灯片方向的自定义值似乎已损坏。 https://stackblitz.com/edit/react-framer-motion-slideshow-official-context?file=src%2FSlideShow.js
您知道如何在使用上下文时让动画再次正常工作吗?
每当上下文的状态发生变化时,所有消耗上下文的东西 re-renders。所以 Slides
组件的 children
- 重新渲染
- 看到新的变体=到下一个状态
- 出现在目的地
如果我是你,我不会使用上下文。如果你真的不想一遍又一遍地明确传递相同的道具,你可以这样做
{[
MainSettingsSlide,
ChangeLanguageSlide,
LanguageDetailsSlide,
BlockedSitesSlide
].map((Component, i) => (
<Component
activeSlideName={activeSlideName}
onNavigateSidebar={onNavigateSidebar}
key={i}
/>
))}
抱歉间接回答:)
两天后编辑
在重读你的问题时,我意识到还有一些其他问题
- 您需要始终根据道具而不是上下文有条件地渲染
const Slide = ({ children, slideName, className, activeSlideName }) => {
// This context will update outside of framer-motion
// framer-motion animating something in while it is animating something out is
// predicated on you giving it control by using props
// const { activeSlideName } = useSlideShowContext();
// console.log('activeSlideName in Slide', activeSlideName);
// console.log('---------------------');
if (activeSlideName !== slideName) {
return null;
}
- 您的
onNavigateSlideShow
使用的是 slideDirection 而不是 direction
const onNavigateSlideShow = ({ slide, direction = 'forward' }) => {
// const onNavigateSlideShow = ({ slide, slideDirection = 'forward' }) => {
console.log('ccc', direction);
setActiveSlide([slide, direction]);
};
- 我仍然无法找到正确方向的指示
我认为这是由于设置方向和动画开始之间的竞争条件造成的
如果您在动画完成之前单击后退按钮,它会按预期工作。
很抱歉,这又不是一个完整的答案。我想我得出的结论和以前一样,这两个 API 可能不应该混用。特别是由于像这样的边缘情况。
最近有很多关于上下文和 AnimatePresence 的问题,所以我为大多数我能想到的情况制作了沙盒:https://codesandbox.io/s/framer-motion-using-context-with-animate-presensce-nuj0m
我有一个状态存储在本地的幻灯片版本,您可以看到幻灯片效果很好,只有在动画完成后才会卸载幻灯片组件。 https://stackblitz.com/edit/react-framer-motion-slideshow-official?file=src%2FSlideShow.js
一旦我添加了上下文来处理这些值,动画滑动仍然有效,但是当动画开始时,现有的组件被新的幻灯片内容替换,这看起来很奇怪。此外,幻灯片方向的自定义值似乎已损坏。 https://stackblitz.com/edit/react-framer-motion-slideshow-official-context?file=src%2FSlideShow.js
您知道如何在使用上下文时让动画再次正常工作吗?
每当上下文的状态发生变化时,所有消耗上下文的东西 re-renders。所以 Slides
组件的 children
- 重新渲染
- 看到新的变体=到下一个状态
- 出现在目的地
如果我是你,我不会使用上下文。如果你真的不想一遍又一遍地明确传递相同的道具,你可以这样做
{[
MainSettingsSlide,
ChangeLanguageSlide,
LanguageDetailsSlide,
BlockedSitesSlide
].map((Component, i) => (
<Component
activeSlideName={activeSlideName}
onNavigateSidebar={onNavigateSidebar}
key={i}
/>
))}
抱歉间接回答:)
两天后编辑
在重读你的问题时,我意识到还有一些其他问题
- 您需要始终根据道具而不是上下文有条件地渲染
const Slide = ({ children, slideName, className, activeSlideName }) => {
// This context will update outside of framer-motion
// framer-motion animating something in while it is animating something out is
// predicated on you giving it control by using props
// const { activeSlideName } = useSlideShowContext();
// console.log('activeSlideName in Slide', activeSlideName);
// console.log('---------------------');
if (activeSlideName !== slideName) {
return null;
}
- 您的
onNavigateSlideShow
使用的是 slideDirection 而不是 direction
const onNavigateSlideShow = ({ slide, direction = 'forward' }) => {
// const onNavigateSlideShow = ({ slide, slideDirection = 'forward' }) => {
console.log('ccc', direction);
setActiveSlide([slide, direction]);
};
- 我仍然无法找到正确方向的指示 我认为这是由于设置方向和动画开始之间的竞争条件造成的
如果您在动画完成之前单击后退按钮,它会按预期工作。
很抱歉,这又不是一个完整的答案。我想我得出的结论和以前一样,这两个 API 可能不应该混用。特别是由于像这样的边缘情况。
最近有很多关于上下文和 AnimatePresence 的问题,所以我为大多数我能想到的情况制作了沙盒:https://codesandbox.io/s/framer-motion-using-context-with-animate-presensce-nuj0m