You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React use client组件传setShow遇TS71007警告:原因与解决

解决React+TypeScript中Props must be serializable for components in the "use client" entry file警告

为什么会触发这个警告?

这个警告是Next.js App Router的TypeScript检查规则(错误码TS71007)导致的:

  • 标记了"use client"的组件,Next.js会默认校验其接收的所有props是否可序列化(即能被转换为JSON的类型,比如字符串、数字、普通对象/数组)。
  • setShow是React的状态更新函数(类型为Dispatch<SetStateAction<boolean>>),属于不可序列化的值(函数无法被JSON序列化),因此触发了这个校验警告。

setShow作为Prop名有问题吗?

完全没有问题。警告里提到"setShow"只是因为它是你传递的那个不可序列化prop的名称,和命名本身无关——哪怕你改成updateVisible、toggleModal这类名字,只要传递的是状态更新函数或其他不可序列化值,都会触发同样的警告。

如何消除警告?

根据你的组件结构,有几种可行方案:

1. 显式声明Props类型并忽略特定规则

如果子组件确实需要接收状态更新函数,可以先明确组件的Props类型,然后在传递props的位置或组件定义处忽略Next.js的不可序列化props检查:

// 子组件(use client)
'use client';
import { Dispatch, SetStateAction } from 'react';

interface ChildProps {
  setShow: Dispatch<SetStateAction<boolean>>;
}

export default function Child({ setShow }: ChildProps) {
  return <button onClick={() => setShow(false)}>关闭</button>;
}

在父组件传递props时添加忽略注释:

// 父组件
import Child from './Child';
import { useState } from 'react';

export default function Parent() {
  const [show, setShow] = useState(true);
  // eslint-disable-next-line @next/next/no-unserializable-props
  return <Child setShow={setShow} />;
}

2. 将状态逻辑移到客户端组件内部

如果子组件是独立的客户端组件,可以把show的状态直接放在子组件里,避免从父组件传递更新函数:

// 子组件(use client)
'use client';
import { useState } from 'react';

export default function Child() {
  const [show, setShow] = useState(true);
  return show ? <button onClick={() => setShow(false)}>关闭</button> : null;
}

3. 将父组件标记为"use client"(若父组件是服务器组件)

如果父组件是未标记"use client"的服务器组件,它本身不能传递不可序列化的props(比如函数)给客户端组件。这种情况下,给父组件添加"use client"标记,让它成为客户端组件,就可以正常传递状态更新函数了:

// 父组件(改为客户端组件)
'use client';
import Child from './Child';
import { useState } from 'react';

export default function Parent() {
  const [show, setShow] = useState(true);
  return <Child setShow={setShow} />;
}

4. 使用React Context传递状态更新逻辑

如果需要在多个组件间共享状态更新函数,可以用Context封装状态逻辑,避免直接传递函数props:

// 定义Context(use client)
'use client';
import { createContext, useContext, useState, Dispatch, SetStateAction } from 'react';

interface ShowContextType {
  show: boolean;
  setShow: Dispatch<SetStateAction<boolean>>;
}

const ShowContext = createContext<ShowContextType | null>(null);

export function ShowProvider({ children }: { children: React.ReactNode }) {
  const [show, setShow] = useState(true);
  return <ShowContext.Provider value={{ show, setShow }}>{children}</ShowContext.Provider>;
}

export function useShow() {
  const context = useContext(ShowContext);
  if (!context) throw new Error('useShow must be used within ShowProvider');
  return context;
}

然后在子组件中使用:

// 子组件(use client)
'use client';
import { useShow } from './ShowContext';

export default function Child() {
  const { setShow } = useShow();
  return <button onClick={() => setShow(false)}>关闭</button>;
}

内容的提问来源于stack exchange,提问作者Ali Baghban

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 08:16:07