直接调用功能组件

时间:2018-08-27 21:14:12

标签: javascript reactjs

无状态功能组件只是一个接收props并返回React元素的函数:

const Foo = props => <Bar />;

这样,可以省略父组件中的<Foo {...props} />(即React.createElement(Foo, props)),而直接调用Foo Foo(props),这样React.createElement的开销很小被淘汰,但这不是必需的。

使用props参数直接调用功能组件是否被视为错误的做法,为什么?这样做可能有什么含义?这会否对性能产生负面影响?

我的具体情况是,有一些组件是DOM元素的浅层包装,因为第三方认为这是个好主意:

function ThirdPartyThemedInput({style, ...props}) {
  return <input style={{color: 'red', ...style}} {...props} />;
}

这是一个显示这种情况的demo

这是一种被广泛接受的做法,但问题在于无法从无状态函数中获取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);

这种方式可以用作:

<ThemedInput ref={inputRef} />
...
inputRef.current.focus();

我知道的明显缺点是withRef要求开发人员知道包装组件的实现,这不是HOC的通常要求。

在上述情况下,它是否被视为正确的方法?

2 个答案:

答案 0 :(得分:1)

我认为直接调用无状态功能组件没有任何问题。正如您所说,这甚至消除了很小的开销。关于可能的影响,大胆地说没有影响,将来也没有影响,因为这是使用证监会的一种罕见方法。但是,所有内容都得出结论,不应有任何含义(仅需少调用一个函数)。

无论如何,下面我想提出一种使用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;
}

// 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'));

直播时间:https://stackblitz.com/edit/react-bpqicw

答案 1 :(得分:0)

当您不需要使用任何生命周期方法或不需要更新组件状态时,功能组件非常有用。就您不需要它们而言,您很好,但最好还是使用无状态组件。

这不会影响性能问题,但会获得有关性能的利润,因为我们只是使用函数来渲染组件,而无需关心其更新,安装,接收道具等。但是仍然没有100%的增长使用无状态组件,因为在内部反应是使用类来呈现它们。

It's about 45% improvement.

post还将指导在有状态组件和无状态组件之间进行选择。


此外,您不仅可以接收道具,还可以接收裁判:

const stateless = (props, ref) => <ReturnComponent {...props} ref={ref} />

好的,让我完善我的陈述。大多数博客甚至文档都指出无状态组件没有引用。以下是有关此问题的一些问答:

  

我是否仅需使用statefull组件即可使用ref?

不。我已经提到过,如果必须使用组件状态或使用某些生命周期方法,则必须使用基于类的组件。

  

如何在无状态组件中创建引用?

const stateless = () => {

  // we can't do this.myRef = React.createRef()
  // so, let's create an object
  const RefObj = {}

  // now, create ref in {RefObj}
  RefObj.myRef = React.createRef()

  return <input type="text" ref={myRef} />
}