React + TypeScript:元素引用的传递
Posted wayou
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React + TypeScript:元素引用的传递相关的知识,希望对你有一定的参考价值。
React 中需要操作元素时,可通过 React 中的元素引用正常的组件中,可通过创建对元素的引用来获取到某元素然后进行相应操作。比如元素加载后将焦点定位到输入框。 class App extends Component {
constructor(props){
super(props);
this.inputRef = React.createRef();
}
componentDidMount(){
this.inputRef.current.focus()
}
render() {
return (
<div className="App">
<input type="text" ref={this.inputRef}/>
</div>
);
}
} 创建对元素的引用是通过 React 内部对引用的 if(this.inputRef.current){
this.inputRef.current.focus()
} 在上面的示例中,之所以不用判空是因为我们在 组件中引用的传递对于原生 DOM 元素可以像上面那样创建引用,但对于自己写的组件,则需要使用 假如你写了个按钮组件,想要实现像上面那样,让使用者可通过传递一个 button.jsx const FancyInput = props => <input type="text" className="fancy-input" />; 添加 ref 支持后的按钮组件: button.jsx const FancyInput = React.forwardRef((props, ref) => {
return <input type="text" ref={ref} className="fancy-input" />;
});
使用上面创建的 class App extends Component {
constructor(props) {
super(props);
this.inputRef = React.createRef();
}
componentDidMount() {
if (this.inputRef.current) {
this.inputRef.current.focus();
}
}
render() {
return (
<div className="App">
- <input type="text" ref={this.inputRef}/>
+ <FancyInput ref={this.inputRef} />
</div>
);
}
} TypeScript 中传递引用先看正常情况下,对原生 DOM 元素的引用。还是上面的示例: class App extends Component<{}, {}> {
private inputRef = React.createRef();
componentDidMount() {
/** ?? Object is possibly ‘null‘ */
this.inputRef.current.focus();
}
render() {
return (
<div className="App">
{/* ?? Type ‘{}‘ is missing the following properties from type ‘htmlInputElement‘:... */}
<input type="text" ref={this.inputRef} />
</div>
);
}
} 像上面那样创建并使用存在两个问题。 一个是提示我们的引用无法赋值到 function createRef<T>(): RefObject<T>; 所以上面创建引用时,显式指定它的类型。 - private inputRef = React.createRef();
+ private inputRef = React.createRef<HTMLInputElement>(); 第二个问题是即使在 componentDidMount() {
+ if(this.inputRef.current){
this.inputRef.current.focus();
+ }
} 还可通过变量后添加 componentDidMount() {
- this.inputRef.current.focus();
+ this.inputRef.current!.focus();
} 修复后完整的代码如下: class App extends Component<{}, {}> {
private inputRef = React.createRef<HTMLInputElement>();
componentDidMount() {
this.inputRef.current!.focus();
}
render() {
return (
<div className="App">
<input type="text" ref={this.inputRef} />
</div>
);
}
} React + TypeScript 组件引用的传递继续到组件的情况,当需要引用的元素在另一个组件内部时,还是通过 这是该方法的签名: function forwardRef<T, P = {}>(Component: RefForwardingComponent<T, P>): ForwardRefExoticComponent<PropsWithoutRef<P> & RefAttributes<T>>; 可以看到,方法接收两个类型参数, 所以添加引用传递后, const FancyInput = React.forwardRef<HTMLInputElement, {}>((props, ref) => {
return <input type="text" ref={ref} className="fancy-input" />;
}); 使用组件: class App extends Component<{}, {}> {
private inputRef = React.createRef<HTMLInputElement>();
componentDidMount() {
this.inputRef.current!.focus();
}
render() {
return (
<div className="App">
<FancyInput ref={this.inputRef} />
</div>
);
}
} 相关资源 |
以上是关于React + TypeScript:元素引用的传递的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Typescript 在 React 中定义 <video> 引用的类型?
TypeScript:为样式化的组件元素扩展 React 组件道具
如何使用 TypeScript 以类型安全的方式访问 React 子元素道具?
React + ApolloProvider + Typescript = "JSX 元素类不支持属性" 错误