代码之家  ›  专栏  ›  技术社区  ›  Estus Flask

直接调用功能组件

  •  8
  • Estus Flask  · 技术社区  · 7 年前

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

    const Foo = props => <Bar />;
    

    这种方式 <Foo {...props} /> (即 React.createElement(Foo, props) )在父组件中可以省略,以便调用 Foo 直接地, Foo(props) 如此 React.createElement 很小的开销可以消除,但这不是必要的。

    直接使用 道具 争论,为什么?这样做可能产生什么影响?这会对性能产生负面影响吗?

    我的具体情况是,有一些组件在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 要求开发人员了解封装组件实现,这不是hocs通常的要求。

    在上述情况下,是否认为这是一种适当的方法?

    2 回复  |  直到 7 年前
        1
  •  1
  •   marzelin    7 年前

    findDOMNode

    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

        2
  •  0
  •   Bhojendra Rauniyar    7 年前

    It's about 45% improvement.

    post


    const stateless = (props, ref) => <ReturnComponent {...props} 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} />
    }