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

React组件报错TypeError:无法读取null的value属性及输入值异常

问题分析与解决方案

核心问题原因

  1. Ref引用混乱:你定义了内部inputRef但未绑定到输入框,反而让输入框直接使用props.innerRef,同时在useEffect中将未绑定的inputRef.current(值为null)赋值给props.innerRef.current,导致父组件通过innerRef访问输入框时拿到null,触发Cannot read properties of null (reading 'value')错误。
  2. 输入框受控状态与外部ref冲突:输入框是受控组件(绑定了inputValue状态),直接将外部ref绑定到输入框可能导致外部操作干扰内部状态,引发显示异常。

修复步骤

  1. 将输入框的ref绑定到组件内部的inputRef,确保内部ref能正确指向输入框元素。
  2. 保留useEffect中向props.innerRef传递内部ref的逻辑,让父组件仍能通过innerRef访问输入框,同时避免覆盖输入框的原始ref引用。
  3. 合并键盘事件逻辑,移除重复的onKeyPress处理,简化代码。

修改后的完整代码

import { useState, useRef, useEffect } from "react";

const SkillsInput = (props) => {
  const [tags, setTags] = useState(props.tags.split(", "));
  const [inputValue, setInputValue] = useState('');
  const inputRef = useRef(null);

  useEffect(() => {
    if (props.innerRef) {
      props.innerRef.current = inputRef.current;
    }
  }, [props.innerRef]);

  const removeTags = (indexToRemove) => {
    const updatedTags = [...tags];
    updatedTags.splice(indexToRemove, 1);
    setTags(updatedTags);
    props.selectedTags(updatedTags);
  };

  const addTags = (event) => {
    if (event.key === "Enter") {
      event.preventDefault(); // 统一处理阻止默认行为
      if (inputValue.trim() !== "") {
        const newTag = inputValue;
        const newTags = [...tags, newTag];
        setTags(newTags);
        props.selectedTags(newTags);
        setInputValue('');
      }
    }
  };

  return (
    <div className='form-control w-full my-2'>
      <label className='label'>
        <span className='label-text text-dark dark:text-lightOne text-base capitalize'>
          {props.name}
        </span>
      </label>
      <div className="flex items-center flex-wrap input input-bordered h-auto bg-main-bg dark:bg-main-dark-bg">
        <div className='flex flex-wrap justify-start items-center'>
          {tags.map((tag, index) => (
            <li
              key={index}
              className='w-auto h-8 flex justify-center items-center text-white px-2 text-sm rounded-md bg-main my-2 mr-2'
            >
              <span>{tag}</span>
              <span
                className='block w-5 h-5 leading-4 text-center text-md ml-2 text-main rounded-full bg-lightOne cursor-pointer font-bold'
                onClick={() => removeTags(index)}
              >
                x
              </span>
            </li>
          ))}
        </div>
        <input
          ref={inputRef} // 绑定内部ref
          name={props.name}
          type='text'
          className='bg-main-bg dark:bg-main-dark-bg outline-none my-2 flex-1'
          value={inputValue}
          onChange={(e) => setInputValue(e.target.value)}
          onKeyUp={addTags}
          placeholder='Press enter to add tags'
        />
      </div>
    </div>
  );
};

export default SkillsInput;

额外说明

  • 修复后,输入框的受控状态(inputValue)会正常更新,不会再出现值为null的情况。
  • 父组件通过innerRef仍能正常访问输入框元素,同时不会干扰内部受控状态的逻辑。
  • 合并了键盘事件的preventDefault处理,避免重复逻辑,代码更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 04:27:02