ReactHook ImperativeHandleHook以及React.forwardRef

React.forwardRef
	使得父組件能夠操作子組件的ref
	
	1、子組件
		const 子組件 = React.forwardRef((props, ref) => {
		return(
			  <div>
			    <input ref={ref} type="text" />
			    <button>{props.children}</button>
			  </div>
			)
		});
		
	2、父組件
	將父組件的ref綁定到子組件上就可操控子組件,ref.current.xxx
		function App() {
		  const ref = useRef();
		  return (
		    <div>
		      <子組件 ref={ref}>Click Me</子組件>
		    </div>
		  )
		}
		
ImperativeHandleHook
	當使用React.forwardRef時,父組件的ref和子組件的ref都是同一個ref
	當使用ImperativeHandleHook,可以使得父組件和子組件擁有各自的ref,並且子組件可選擇性地暴露其他內容
	
	1、子組件
		const 子組件= React.forwardRef((props, ref) => {
		  const inputRef = useRef();
		  
		  useImperativeHandle(ref, () =>{
			  return{  暴露給父組件的ref的值
		  			focus: () => {
		      			inputRef.current.focus();
		    		},
		    		其他內容...
		  		}
		  });
		
		  return <input ref={inputRef} type="text" />
		});
		
	2、父組件
		將父組件的ref綁定到子組件上,就可獲取子組件通過ref暴露的內容,父組件Ref.current.子組件暴露的內容
		const App = props => {
		  const 父組件Ref = useRef();
			
		  return (
		    <div>
		      <子組件 ref={fancyInputRef} />
		      <button
		        onClick={() => fancyInputRef.current.focus()}
		      >父組件調用子組件的 focus</button>
		    </div>
		  )
		}

代碼示例:
React.forwardRef:

import React, { useCallback, useRef } from 'react';
import ReactDOM from 'react-dom';

// 實現 ref 的轉發
const FancyButton = React.forwardRef((props, ref) => (
  <div>
    <input ref={ref} type="text" />
    <button>{props.children}</button>
  </div>
));

// 父組件中使用子組件的 ref
function App() {
  const ref = useRef();
  const handleClick = useCallback(() => ref.current.focus(), [ ref ]);

  return (
    <div>
      <FancyButton ref={ref}>Click Me</FancyButton>
      <button onClick={handleClick}>獲取焦點</button>
    </div>
  )
}

ReactDOM.render(<App />, root);

ImperativeHandleHook:

import React, { useRef, useImperativeHandle } from 'react';
import ReactDOM from 'react-dom';

const FancyInput = React.forwardRef((props, ref) => {
  const inputRef = useRef();
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    }
  }));

  return <input ref={inputRef} type="text" />
});

const App = props => {
  const fancyInputRef = useRef();

  return (
    <div>
      <FancyInput ref={fancyInputRef} />
      <button
        onClick={() => fancyInputRef.current.focus()}
      >父組件調用子組件的 focus</button>
    </div>
  )
}

ReactDOM.render(<App />, root);

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章