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

Next.js SSR环境下如何通过React Hooks实现onClick DOM操作

在Next.js SSR环境下实现点击操作DOM的正确方式

嘿,刚接触React和Next.js踩SSR的坑太正常了,我帮你把问题捋清楚,再给你两种靠谱的解决方案~

首先得先指出你原来代码里的几个小问题:

  • onClick写法错误:你写的onClick={menu()}是页面一渲染就直接执行menu函数了,不是点击的时候才触发,正确写法应该是onClick={menu}或者用箭头函数包裹onClick={() => menu()}
  • DOM操作逻辑错误:document.getElementsByClassName('menu')返回的是一个元素集合(HTMLCollection),不是单个元素,你得先取到具体元素(比如menu[0])才能用.style,但这还不是最关键的问题
  • SSR环境限制:服务器端渲染时根本没有浏览器的document对象,直接这么写会直接报错,而且React本身也不推荐直接操作DOM,更建议用状态来控制UI变化

方案一:React推荐的「状态驱动UI」方式(更符合React思想)

这种方式完全不用直接操作DOM,用useState维护状态来控制样式,完美适配SSR:

import { useState } from 'react';
import styles from './your-component.module.css'; // 替换成你的样式文件路径

export default function YourComponent() {
  // 用状态存储菜单的宽高样式
  const [menuStyle, setMenuStyle] = useState({
    width: 'auto',
    height: 'auto'
  });

  const handleMenuClick = () => {
    // 点击时更新状态,React会自动重新渲染并应用新样式
    setMenuStyle({
      width: '400px',
      height: '400px'
    });
  };

  return (
    <div className={styles.menuCon} onClick={handleMenuClick}>
      {/* 将状态中的样式绑定到目标元素 */}
      <div className={styles.menu} style={menuStyle}></div>
      <div></div>
      <div></div>
    </div>
  );
}

简单说,就是把你要修改的样式放到状态里,点击事件只负责更新状态,剩下的UI更新交给React自动处理,完全规避了DOM操作的问题,SSR环境下也不会报错。

方案二:如果确实需要直接操作DOM(用useRef安全实现)

如果你有复杂的DOM操作需求,必须直接操作元素,可以用useRef获取元素引用,同时确保代码只在客户端执行:

import { useRef } from 'react';
import styles from './your-component.module.css';

export default function YourComponent() {
  // 用useRef创建一个引用,用来绑定目标DOM元素
  const menuRef = useRef(null);

  const handleMenuClick = () => {
    // 先判断引用是否指向了真实的DOM元素,避免空指针错误
    if (menuRef.current) {
      menuRef.current.style.width = '400px';
      menuRef.current.style.height = '400px';
    }
  };

  return (
    <div className={styles.menuCon} onClick={handleMenuClick}>
      {/* 将ref绑定到目标元素上 */}
      <div className={styles.menu} ref={menuRef}></div>
      <div></div>
      <div></div>
    </div>
  );
}

这里的useRef可以帮你直接拿到DOM元素的引用,不用通过document去查找,而且点击事件只有在客户端页面渲染完成后才会触发,所以不会碰到SSR时document不存在的问题。

最后再啰嗦一句:React的核心是状态驱动UI,能不用直接操作DOM就尽量不用,这样代码更易维护,也能避免很多奇怪的bug~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 16:22:42