直接调用功能组件

问题描述 投票:8回答:2

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

const Foo = props => <Bar />;

这样,父组件中的<Foo {...props} />(即React.createElement(Foo, props))可以省略,有利于直接调用FooFoo(props),因此可以消除React.createElement微小开销,但这不是必需的。

props参数直接调用函数组件被认为是一种不好的做法,为什么?这样做有什么可能的影响?这会以负面的方式影响性能吗?

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

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

这是一个demo,显示了这种情况。

这是一种被广泛接受的做法,但问题在于无法从无状态函数中获取包装DOM元素的ref,因此该组件使用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的通常要求。

在上述情况下,它被认为是一种正确的方法吗?

javascript reactjs
2个回答
1
投票

我认为直接调用无状态功能组件没有任何问题。正如你所说,它甚至消除了一个微小的开销。至于可能的含义,可以大胆地说,没有任何影响,将来不会有任何影响,因为这是一种非常罕见的使用SFC的方式。但是一切都指出不应该有任何影响(它只是一个函数调用更少)。

无论如何,下面我想介绍另一种方法,使用findDOMNode而不是refs:

我已经创建了Focus组件,它非常方便使用,但需要首先进行初始化(因为我们需要一种方法来触发道具之外的焦点,因为组件可能会使用相同的道具重新渲染):

// 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


0
投票

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

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

It's about 45% improvement.

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


此外,您不仅可以收到道具,还可以收到参考:

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

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

我是否需要使用有状态组件才能使用ref?

不,我已经提到过,如果我们必须使用组件状态或挂钩一些生命周期方法,我们必须要求基于类的组件。

如何在无状态组件中创建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} />
}
© www.soinside.com 2019 - 2024. All rights reserved.