ref 和 React.js 中的 DOM 操作

在 React.js 当中你基本不需要和 DOM 直接打交道。React.js 提供了一系列的 on*方法帮助我们进行事件监听,所以 React.js 当中不需要直接调用 addEventListener的 DOM API;以前我们通过手动 DOM 操作进行页面更新(例如借助 jQuery),而在 React.js 当中可以直接通过 setState 的方式重新渲染组件,渲染的时候可以把新的 props 传递给子组件,从而达到页面更新的效果。

React.js 这种重新渲染的机制帮助我们免除了绝大部分的 DOM 更新操作,也让类似于 jQuery 这种以封装 DOM 操作为主的第三方的库从我们的开发工具链中删除。

但是 React.js 并不能完全满足所有 DOM 操作需求,有些时候我们还是需要和 DOM 打交道。比如说你想进入页面以后自动 focus 到某个输入框,你需要调用 input.focus() 的 DOM API,比如说你想动态获取某个 DOM 元素的尺寸来做后续的动画,等等。

React.js 当中提供了 ref 属性来帮助我们获取已经挂载的元素的 DOM 节点,你可以给某个 JSX 元素加上 ref属性:

class AutoFocusInput extends Component {
  componentDidMount () {
    this.input.focus()
  }

  render () {
    return (
      <input ref={(input) => this.input = input} />
    )
  }
}

ReactDOM.render(
  <AutoFocusInput />,
  document.getElementById('root')
)

可以看到我们给 input 元素加了一个 ref 属性,这个属性值是一个函数。当 input 元素在页面上挂载完成以后,React.js 就会调用这个函数,并且把这个挂载以后的 DOM 节点传给这个函数。在函数中我们把这个 DOM 元素设置为组件实例的一个属性,这样以后我们就可以通过 this.input 获取到这个 DOM 元素。

然后我们就可以在 componentDidMount 中使用这个 DOM 元素,并且调用 this.input.focus() 的 DOM API。整体就达到了页面加载完成就自动 focus 到输入框的功能(大家可以注意到我们用上了 componentDidMount 这个组件生命周期)。

我们可以给任意代表 HTML 元素标签加上 ref 从而获取到它 DOM 元素然后调用 DOM API。但是记住一个原则:能不用 ref 就不用。特别是要避免用 ref 来做 React.js 本来就可以帮助你做到的页面自动更新的操作和事件监听。多余的 DOM 操作其实是代码里面的“噪音”,不利于我们理解和维护。

顺带一提的是,其实可以给组件标签也加上 ref ,例如:

<Clock ref={(clock) => this.clock = clock} />

这样你获取到的是这个 Clock 组件在 React.js 内部初始化的实例。但这并不是什么常用的做法,而且也并不建议这么做,所以这里就简单提及,有兴趣的朋友可以自己学习探索。

转载于:https://www.cnblogs.com/hanmeimei/p/8796775.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、React.useState() 是 React 一个 Hook 函数,用于在函数组件添加状态。它返回一个包含当前状态值和更新状态值的数组,可以通过解构赋值获取这两个值。 使用案例: ```javascript import React, { useState } from 'react'; function Counter() { const [count, setCount] = useState(0); return ( <div> <p>Count: {count}</p> <button onClick={() => setCount(count + 1)}>Increment</button> </div> ); } ``` 在上面的例子,我们使用了 useState() 来创建一个名为 count 的状态变量和一个名为 setCount 的函数。初始值为 0。通过解构赋值,我们可以将 count 的当前值展示在页面上,并在点击按钮时通过 setCount 将 count 的值加1,实现计数器的功能。 2、React.useEffect() 是 React 的另一个 Hook 函数,用于在函数组件执行副作用操作,比如订阅数据、修改 DOM 等。它在组件渲染完成后执行,并且可以在组件更新时重新执行。 使用案例: ```javascript import React, { useState, useEffect } from 'react'; function DataFetcher() { const [data, setData] = useState(null); useEffect(() => { // 在组件渲染完成后执行这里的回调函数 fetchData(); }, []); const fetchData = async () => { const response = await fetch('https://api.example.com/data'); const data = await response.json(); setData(data); }; return ( <div> {data ? ( <ul> {data.map((item) => ( <li key={item.id}>{item.name}</li> ))} </ul> ) : ( <p>Loading data...</p> )} </div> ); } ``` 在上面的例子,我们使用 useEffect() 来执行 fetchData() 函数,该函数通过网络请求获取数据,并将数据更新到组件的状态。通过传递一个空数组作为第二个参数,我们告诉 React 只在组件渲染完成后执行一次 useEffect(),避免重复执行。 3、React.useRef() 是 React 的又一个 Hook 函数,用于在函数组件创建一个可变的 ref 对象。ref 对象可以存储任意可变值,类似于在 class 组件使用的实例属性。 使用案例: ```javascript import React, { useRef } from 'react'; function InputFocus() { const inputRef = useRef(null); const handleClick = () => { inputRef.current.focus(); }; return ( <div> <input ref={inputRef} type="text" /> <button onClick={handleClick}>Focus Input</button> </div> ); } ``` 在上面的例子,我们使用 useRef() 创建了一个名为 inputRefref 对象,并将其赋值给 input 元素ref 属性。在点击按钮时,通过调用 inputRef.current.focus(),我们可以将焦点设置到输入框上。 总结: - React.useState() 用于在函数组件添加状态。 - React.useEffect() 用于执行副作用操作,比如订阅数据或修改 DOM。 - React.useRef() 用于创建一个可变的 ref 对象,类似于在 class 组件使用的实例属性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值