React - 渲染内部的 HOC - 规则有例外吗?

Posted

技术标签:

【中文标题】React - 渲染内部的 HOC - 规则有例外吗?【英文标题】:React - HOCs Inside Render - Are there Exceptions to the Rule? 【发布时间】:2021-01-28 10:21:44 【问题描述】:

我通过使用多种组件组合技术实现了 Pub/Sub 模式:React.cloneElement 和功能性“组合组件”。我们的目标是能够通过为组件分配“主题”属性来将组件动态注册到不同的数据流中。

例如,该组件接收发布到 HELLO_WORLD 主题的所有数据:

 <MyComponent topic="HELLO_WORLD" />

这里是 MyComponent 内部表示为一个函数式组件:

export const MyComponent = props => subscribe(( topic, data ) => 
    return <span>I am listening to the topic topic. Current state: data</span>
, props.topic);

或者,这里表示为类组件:

class MyComponent extends React.Component 
    render() 
        const  props:  otherProps, topic   = this;
        return subscribe(( data ) => 
            return <span>I am listening to the topic topic. Current state: data</span>
        , topic)
    

如您所见,这种模式需要在渲染函数中返回一个高阶组件。你认为这属于here 提到的警告吗?

这里有更多上下文:

subscribe 函数返回一个组合组件:

const subscribe = (Comp, topic) => 
  return (
    <Subscriber topic=topic>
      <Comp />
    </Subscriber>
  );
;

将 MyComponent 包装在订阅者中:

class Subscriber extends Component 
    state = publisher.getState(this.props.topic) // get initial state

    onMessage = msg => 
        this.setState( ...msg );
        return this.state;
    

    componentDidMount() 
        this.subscription = publisher
            .subscribe(this.props.topic, this.onMessage);
    
    
    componentWillUnmount() 
        publisher.unsubscribe(this.props.topic, this.onMessage);
    

    render() 
        const 
            state:  data ,
            props:  children 
         = this;
        return Children.map(children, child =>
            cloneElement(child,  ...this.props, data )
        );
    

订阅者从发布者那里获取状态,发布者缓存主题:

const eventEmitter = new EventEmitter();

const publisher = 
  subscribe: function (eventName, cache) 
    eventEmitter.on(eventName, data => 
      this.cache[eventName] = cache(data);
    );
  ,
  unsubscribe: function (eventName, fn) 
    eventEmitter.off(eventName, fn)
  ,
  send: function (eventName, payload) 
    eventEmitter.emit(eventName, payload);
    if (!this.cache[eventName]) 
      this.cache[eventName] =  data: payload ;
    
  ,
  getState: function (topic) 
    return this.cache[topic] || ;
  ,
  cache: 

组件分析器表明此设置的渲染效率很高。此外,状态保存在 React 领域之外的缓存中。如果你问我,它几乎只是 Flux 的一个转折点。你的想法?

【问题讨论】:

我在您的代码中没有看到任何 HOC。您能指出来吗?? HOC 是一个纯函数,它以 component 作为输入并通过将 component 包装在容器中来返回零件。我在您的代码中没有看到任何 HOC。你能指出来吗?? MyComponent 的 render 方法中显示的 subscribe() 函数接受一个组件作为参数并将其包装在订阅者组件中。 【参考方案1】:

您的 subscribe() 不是真正的 HOC。

为什么? (集中在粗体字上)

HOC 是一个纯 Function,它返回一个容器组件 包装原始组件。 subscribe() 只是包装器 Component 只是包装 原始组件并返回。

这是一个详细的答案: https://***.com/a/64178585/8323442

【讨论】:

以上是关于React - 渲染内部的 HOC - 规则有例外吗?的主要内容,如果未能解决你的问题,请参考以下文章

react hook下的hoc组件

我应该在我的 HOC 中哪里使用 useEffect 来接收 React 中的道具?

[react] 什么渲染劫持?

React Hook - Hook规则

什么是渲染道具,它与高阶组件有什么不同?

是否可以通过使用 HOC(高阶组件)在类组件中使用 React Hooks?