我可以在 React js 中使用 useRef 挂钩而不是 onChange 事件来更新状态吗?

Posted

技术标签:

【中文标题】我可以在 React js 中使用 useRef 挂钩而不是 onChange 事件来更新状态吗?【英文标题】:May I update state using useRef hook instead of onChange event in React js? 【发布时间】:2021-02-11 17:51:03 【问题描述】:

在寻找避免在每次更改输入字段后呈现组件的方法时,我遇到了使用 useRef 而不是 onChange 事件进行状态更新的建议。在简单的组件中似乎还可以,但由于我是初学者,我不知道这在更复杂的应用程序中是否是一种好方法。 Shell 我继续这样还是我应该坚持 onChange 事件? 我进行了很多搜索以解决这个困境,但无法找到明确的答案。任何这方面的建议都会受到更多的欢迎。

这是它在组件中的样子:

import React,  useRef, useState  from 'react';
import axios from 'axios';

const AddData : React.FC= () => 

  const initialData = 
    firstValue: '',
    secondValue : ''            
  
  
  const [data, setData] = useState(initialData);
  const formRef = useRef<htmlFormElement>(null);  
  const firstInputRef = useRef<HTMLInputElement>(null);
  const secondInputRef = useRef<HTMLInputElement>(null);          

  const handleSetData = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) =>     
    if(firstInputRef.current !== null && secondInputRef.current !== null)       
      setData(
        ...data, 
            firstValue: firstInputRef.current.value,
            secondValue: secondInputRef.current.value                           
      )      
        
  

  const handleFormSubmit = async (e:React.FormEvent<HTMLFormElement>) => 
    e.preventDefault();   
    const firstValue, secondValue = data;
    if(firstValue !== '' && secondValue !== '')          
      await axios.post('url', 
        ...data    
      ).then((response) =>   );      
    
     

  return(
    <>      
      <form ref=formRef onSubmit=handleFormSubmit>        
        <input type='text' ref=firstInputRef />
        <input type='text' ref=secondInputRef />            
        <button onClick=handleSetData> Submit Form </button>
      </form >
    </>
  );

export default AddData;

【问题讨论】:

【参考方案1】:

您使用的方法称为非受控表单元素,是官方docs 上受控元素的替代方法。在大多数情况下,React 建议使用受控的,但我想如果你愿意,也可以使用不受控的。

在大多数情况下,我们建议使用受控组件来实现 形式。在受控组件中,表单数据由 React 处理 零件。另一种选择是不受控制的组件,其中表单数据 由 DOM 自己处理。

【讨论】:

感谢您的回答。在处理表单时我是否应该考虑太多关于重新渲染的事情? @ahmed.zubaca 欢迎您,如果对您有帮助,您可以接受答案。如果您有较大的表单或注意到性能问题,您可以考虑重新渲染,在这种情况下,我建议您查看 React.memouseCallback 函数,您可以创建自定义表单组件,如果它们的输入没有更改,则不会重新渲染例如。 你帮了我很多。我现在的理解是,这种不受控制的形式,基本上没有错。谢谢,再来一次。【参考方案2】:

你可以使用

const firstInputRef = useRef (null);

改为

 const firstInputRef = useRef <HTMLFormElement> (null);

react 团队推荐 useRef 是在读取值时推荐使用,由 React 团队推荐。 useRef 将在每次渲染时为您提供相同的 ref 对象,

请记住,useRef 在其内容更改时不会通知您,您想使用函数 useCallback

【讨论】:

以上是关于我可以在 React js 中使用 useRef 挂钩而不是 onChange 事件来更新状态吗?的主要内容,如果未能解决你的问题,请参考以下文章

useRef 是不是在 React 中存储变量的地址

尝试在打字稿中使用 React useref 时出错

在 React 中使用 useRef() 触发 CSS 动画

如何解决反应js中的“useRef不是函数错误”

试图让我们在数组中使用 React 的 useRef 来获取音频的持续时间

这里的 useRef 内部发生了啥?