Est*_*ask 8 javascript reactjs
无状态功能组件只是一个接收props和返回React元素的函数:
const Foo = props => <Bar />;
Run Code Online (Sandbox Code Playgroud)
这种方式<Foo {...props} />(即React.createElement(Foo, props))在父组件中可以省略,有利于Foo直接调用Foo(props),因此React.createElement可以消除微小的开销,但这不是必需的.
用props参数直接调用函数组件被认为是一种不好的做法,为什么?这样做有什么可能的影响?这会以负面的方式影响性能吗?
我的具体情况是,有一些组件是DOM元素的浅包装,因为这被第三方认为是个好主意:
function ThirdPartyThemedInput({style, ...props}) {
return <input style={{color: 'red', ...style}} {...props} />;
}
Run Code Online (Sandbox Code Playgroud)
这是一种被广泛接受的做法,但它的问题在于无法ref从无状态函数中获取包装的DOM元素,因此该组件使用React.forwardRef:
function withRef(SFC) {
return React.forwardRef((props, ref) => SFC({ref, ...props}));
// this won't work
// React.forwardRef((props, ref) => <SFC ref={ref} {...props } />);
}
const ThemedInput = withRef(ThirdPartyThemedInput);
Run Code Online (Sandbox Code Playgroud)
这样它可以用作:
<ThemedInput ref={inputRef} />
...
inputRef.current.focus();
Run Code Online (Sandbox Code Playgroud)
我所知道的明显的缺点是withRef需要开发人员了解包装组件的实现,这不是HOC的通常要求.
在上述情况下,它被认为是一种正确的方法吗?
我不认为直接调用无状态功能组件有什么问题。正如您所说,这甚至消除了一点点开销。至于可能产生的影响,可以大胆地说没有影响,将来也不会产生影响,因为这是一种非常罕见的使用证监会的方式。但一切都表明结论不应该有任何影响(只是少了一个函数调用)。
无论如何,下面我想介绍另一种使用findDOMNode而不是引用来做到这一点的方法:
我创建了Focus使用起来非常方便的组件,但需要首先初始化(因为我们需要一种方法来触发 props 之外的焦点,因为组件可能会使用相同的 props 重新渲染):
// focus.js
import React from "react";
import { findDOMNode } from "react-dom";
export default function createFocus() {
class Focus extends React.Component {
componentDidMount() {
Focus.now = () => {
findDOMNode(this).focus();
}
}
render() {
return this.props.children;
}
}
return Focus;
}Run Code Online (Sandbox Code Playgroud)
// index.js
import React, { Component } from 'react';
import { render } from 'react-dom';
import createFocus from './focus';
const Focus = createFocus();
import { ThirdPartyThemedInput } from './third-party-lib';
function App() {
return (
<div>
<button onClick={() => Focus.now()}>Proceed with form</button>
<Focus>
<ThirdPartyThemedInput placeholder="Fill me" />
</Focus>
</div>
);
}
render(<App />, document.getElementById('root'));Run Code Online (Sandbox Code Playgroud)
直播地址: https: //stackblitz.com/edit/react-bpqicw