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

React添加textarea样式后深色模式无法切回浅色模式的问题

React组件模式切换无法切回浅色模式的原因及修复

问题核心

在switchMode函数中添加修改textarea样式的代码后,无法从深色模式切换回浅色模式,移除该代码后功能恢复正常。

问题原因分析

  1. mode变量未使用React状态管理
    你用let mode = "light"定义的是普通变量,而非React状态。每次组件重渲染(比如调用textAreaStyleFinal更新样式状态时),这个变量都会被重新初始化为"light"。导致第一次切换到深色模式后,组件重渲染,mode又变回"light",下次点击切换时,逻辑会再次执行深色模式的代码,永远无法进入else分支。

  2. 状态变量命名混淆(次要但需修正)
    const [textAreaStyleInitial, textAreaStyleFinal] = useState(...)的命名颠倒了React状态的解构规则:第一个值是当前状态,第二个是更新状态的函数。这种命名不仅可读性极差,还容易引发后续维护错误。

修复方案

修复后的完整代码

import React, { useState } from "react";

export default function TextForm(props) {
  const handleUpClick = () => {
    const newText = text.toUpperCase();
    setText(newText);
  };

  const handleDownClick = () => {
    const newText = text.toLowerCase();
    setText(newText);
  };

  const handleClearClick = () => {
    setText("");
  };

  const handleReverseClick = () => {
    setText(text.split(" ").reverse().join(" "));
  };

  const handleOnChange = (Event) => {
    setText(Event.target.value);
  };

  // 用useState管理mode状态,确保组件重渲染时状态不丢失
  const [mode, setMode] = useState("light");
  const switchMode = () => {
    if (mode === "light") {
      document.body.style.backgroundColor = "black";
      document.body.style.color = "white";
      setMode("dark");
      setTextAreaStyle({
        backgroundColor: "darkgrey",
        color: "darkblue",
      });
    } else {
      document.body.style.backgroundColor = "white";
      document.body.style.color = "black";
      setMode("light");
      setTextAreaStyle({
        backgroundColor: "white",
        color: "black",
      });
    }
  };

  const [text, setText] = useState("");
  // 修正状态命名,符合React规范
  const [textAreaStyle, setTextAreaStyle] = useState({
    backgroundColor: "white",
    color: "black",
  });

  return (
    <>
      <div className="container">
        <h1>{props.heading}</h1>
        <div className="mb-3">
          <textarea
            className="form-control"
            id="exampleFormControlTextarea1"
            rows="3"
            placeholder="Enter Your Text Here"
            value={text}
            onChange={handleOnChange}
            style={textAreaStyle}
          ></textarea>
        </div>
        <button className="btn btn-primary mx-1" onClick={handleUpClick}>
          Convert to Uppercase
        </button>
        <button className="btn btn-primary mx-1" onClick={handleDownClick}>
          Convert to Lowercase
        </button>
        <button className="btn btn-primary mx-1" onClick={handleReverseClick}>
          Reverse Sentence
        </button>
        <button className="btn btn-primary mx-1" onClick={handleClearClick}>
          Clear All
        </button>
      </div>
      <div className="container my-3">
        <div className="form-check form-switch my-3">
          <label className="form-check-label" htmlFor="flexSwitchCheckDefault">
            Enable Dark Mode
          </label>
          <input
            className="form-check-input"
            type="checkbox"
            role="switch"
            id="flexSwitchCheckDefault"
            onChange={switchMode}
          />
        </div>
        <h2>Your Text Summary</h2>
        <p>
          {text.split(" ").filter(word => word.trim() !== "").length} Words and {text.length} characters
        </p>
      </div>
    </>
  );
}

关键修复点说明

  • 将let mode替换为useState("light"),让React追踪mode状态,确保组件重渲染时不会丢失当前模式值。
  • 修正textarea样式的状态命名为textAreaStyle和setTextAreaStyle,符合React状态的命名规范,避免混淆。
  • 额外修复了单词统计的小问题:原代码会把空字符串(比如多个空格)统计为单词,新增filter(word => word.trim() !== "")过滤无效内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 08:50:25