React
支持一种非常特殊的属性 Ref
,你可以用来绑定到 render()
输出的任何组件上。
这个特殊的属性允许你引用 render()
返回的相应的实例
使用方法
绑定一个 ref
属性到 render
的返回值上:
<input ref="myInput" />
通过 this.refs
获取支撑实例:
1 2 3
| var input = this.refs.myInput; var inputValue = input.value; var inputRect = input.getBoundingClientRect();
|
当 Hooks
出现后,Ref
有了一点变化:它可以引用任意值(Dom
Node
或 JavaScript
Value
)
完整的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| function Counter() { const hasClickedButton = React.useRef(false); const [count, setCount] = React.useState(0); function onClick() { const newCount = count + 1; setCount(newCount); hasClickedButton.current = true; } console.log('Has clicked button? ' + hasClickedButton.current); return ( <div> <p>{count}</p> <button type="button" onClick={onClick}> Add </button> </div> ); }
|
const hasClickedButton = React.useRef(false);
DOM REFS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| function App() { return ( <ComponentWithDomApi label="Label" value="Value" isFocus /> ); } function ComponentWithDomApi({ label, value, isFocus }) { const ref = React.useRef(); React.useEffect(() => { if (isFocus) { ref.current.focus(); } }, [isFocus]); return ( <label> {/* (2) */} {label}: <input type="text" value={value} ref={ref} /> </label> ); }
|
- (1) 创建了一个Ref对象且没有赋初始值
- (2) 通过指定input的ref属性与创建的Ref对象关联
- (3) ref.current.focus() 使用input的API
看一个监听文本变化后改变页面标题的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| function ComponentWithRefRead() { const [text, setText] = React.useState('Some text ...'); function handleOnChange(event) { setText(event.target.value); } const ref = React.useRef(); React.useEffect(() => { const { width } = ref.current.getBoundingClientRect(); document.title = `Width:${width}`; }, [text]); return ( <div> <input type="text" value={text} onChange={handleOnChange} /> <div> <span ref={ref}>{text}</span> </div> </div> ); }
|
这个例子也可以采用callback ref实现。
既不需要 useEffect
也不需要 useRef
, 因为每次 re-render
都会执行 callback ref
函数,回调函数会传入绑定的 DOM
节点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| function ComponentWithRefRead() { const [text, setText] = React.useState('Some text ...'); function handleOnChange(event) { setText(event.target.value); } const ref = (node) => { if (!node) return; const { width } = node.getBoundingClientRect(); document.title = `Width:${width}`; }; return ( <div> <input type="text" value={text} onChange={handleOnChange} /> <div> <span ref={ref}>{text}</span> </div> </div> ); }
|
全文完。