Next.js 14 App Router引入 farmer-motion 初始化异常解决,顺带学点知识

前言

farmer-motion 是一个非常好用的动画库,当然用来做组件切换和路由切换过渡更不在话下。

记录一下,Next.js 14 App Router 下引入初始化异常的解决姿势,顺带扯一下 next.js 的知识点;

问题

过渡组件代码

我们拿 farmer-motion 搞一个例子来做演示, 初始化从 X 轴方向右边偏移进来,渐隐渐现的方式。

// SlideLeftTransitionWrapper.tsx
import { motion } from "framer-motion";

export default function Transition({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <motion.div
      initial={{ x: 50, opacity: 0 }}
      animate={{ x: 0, opacity: 1 }}
      transition={{ ease: "easeInOut", duration: 0.75 }}
    >
      {children}
    </motion.div>
  );
}

渲染异常演示

理解及解决

Next.js 路由模式模式简单介绍

next.js 提供了两种路由方式,这里大体点一下,具体可以看官网更加详细

  • Pages Router

    • 定义页面层级路由
    • 所有组件 React Client Component(客户端组件)
    • 只能使用 Next.js 提供的预设规则,例如:文件夹名字即为路径
  • App Router

    • 定义应用程式层级的路由
    • 所有组件预设为 React Server Component(服务层组件)
    • 可自定义路由规则,比如使用正则表达式去匹配特定路径

为什么会渲染异常?

首先 farmer-motion 这个 npm 库,翻源码便可以看到大量能力的实现是依赖浏览器客户端 API 特性;

https://github.com/framer/motion/blob/main/packages/framer-motion/src/dom-entry.ts

其次上面说到了 App Router 默认是服务层组件优先!点到这个就基本知道问题所在了。

在 App Router 中,NextJS 将会区分 Client Components和 Server Components, Server Components 是一种特殊的 React 组件,它不是在浏览器端运行,而是只能在服务器端运行。又因为它们没有状态,所以不能使用只存在于客户端的特性(也就是说 useStateuseEffect 那些都是用不了的,包括 window 对象这些),所以一般我们可以用于获取数据,或者对非客户端组件进行渲染。

你客户端的组件在 Server Components 里面去渲染,不做一点点处理,肯定执行异常!

一点点处理之前的预备知识

那就是 next.js 既然是支持 SSG,SSR 混合式开发的框架。肯定要考虑这类的场景。

他们官方提供了两个特殊的指令: use clientuse server,

这两个指令是什么用呢?
简单粗暴的理解就是告诉框架,我当前这个组件适用于什么场景下渲染;

比如用了 use client, 代表我该组件只在客户端渲染, 拿一个他们文档的例子来说,

比如我们要用到 react 的 useEffectuseStateonClick特性!!

'use client'
 
import { useState } from 'react'
 
export default function Counter() {
  const [count, setCount] = useState(0)
 
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>Click me</button>
    </div>
  )
}

next.js 这两个指令相关介绍可以这两个文档

这两个指令虽然是 next.js 团队提出来并用在了框架里面,
但是很大概率会整到 React 19 里面去。
因为 React 官方文档提供了这两个 API 的说明,并标记为实验性特性!

修正执行

代码修正
"use client";
import { motion } from "framer-motion";

export default function Transition({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <motion.div
      initial={{ x: 50, opacity: 0 }}
      animate={{ x: 0, opacity: 1 }}
      transition={{ ease: "easeInOut", duration: 0.75 }}
    >
      {children}
    </motion.div>
  );
}

还能再抽象一点,比如我们取个名字, MotionElement.tsx

"use client"

import { motion } from "framer-motion";

export const MotionDiv = motion.div;
export const MotionSpan = motion.span;
// ts 推断依旧是保留的
运行效果图

请添加图片描述

总结

最常见的的组件和路由过渡可以看这块(farmer-motion):

写法上,跟styled-components 好像;

有不对之处请留言,会及时修正,谢谢阅读。

相关推荐

  1. MySQL数据库,初学SQL知识引入

    2024-04-22 15:02:03       55 阅读
  2. 3.14word直播知识

    2024-04-22 15:02:03       35 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-22 15:02:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-22 15:02:03       100 阅读
  3. 在Django里面运行非项目文件

    2024-04-22 15:02:03       82 阅读
  4. Python语言-面向对象

    2024-04-22 15:02:03       91 阅读

热门阅读

  1. arm-day8

    2024-04-22 15:02:03       31 阅读
  2. spdlog 日志库部分源码说明

    2024-04-22 15:02:03       38 阅读
  3. 软件测试 -- 自动化测试(Selenium)

    2024-04-22 15:02:03       38 阅读
  4. 2023-2024年人形机器人行业报告合集(精选397份)

    2024-04-22 15:02:03       33 阅读
  5. pcb的几种常见认证

    2024-04-22 15:02:03       33 阅读
  6. uniapp 页面跳转通信上下级页面互传

    2024-04-22 15:02:03       33 阅读
  7. 一文了解什么是RESTful风格

    2024-04-22 15:02:03       32 阅读
  8. SQL Server详细使用教程

    2024-04-22 15:02:03       39 阅读
  9. js实现快速拖拽(定时器版本)

    2024-04-22 15:02:03       34 阅读
  10. Flink CDC 整库 / 多表同步至 Kafka 方案(附源码)

    2024-04-22 15:02:03       31 阅读
  11. 从事数据分析相关工作技术总结

    2024-04-22 15:02:03       28 阅读
  12. FFT快速傅里叶变换音频分析

    2024-04-22 15:02:03       43 阅读
  13. 基于单片机雨天自动关窗器的设计

    2024-04-22 15:02:03       35 阅读
  14. 基础矩阵和本质矩阵

    2024-04-22 15:02:03       39 阅读