如何使用HOC仅在React中渲染具有特定道具的孩子

时间:2019-05-14 00:42:46

标签: javascript reactjs ecmascript-6

我正在创建一个HOC,它将在某个道具{在本例中为onEditable上检查其子代(及其子代)。如果未指定,则假定要显示该子项;如果将其设置为hide,则不会渲染该子项。

(该道具不是布尔值,因为稍后我将添加更多选项)

const MyComponent = ({ children, }) => {
  const getChildren = (myChildren, onEditable = 'show') => React.Children.map(myChildren, (child) => {
    let myOnEditable = onEditable;
    const { props, } = child;
    if (props) {
      const { onEditable: onEdit, children: grandChildren, } = props;
      onEdit && (myOnEditable = onEdit);
      typeof grandChildren === 'object'
          && getChildren(grandChildren, myOnEditable);
    }
    console.log(myOnEditable);
    if (myOnEditable === 'show') {
      return child;
    }
  });
  return <div>{getChildren(children)}</div>;
};

ReactDOM.render(
    <MyComponent>
      <p onEditable="show">show</p>
      Unspecified
      <div onEditable="hide">
        <span onEditable="show">show inside hide</span>
        <p>Unspecified in hide</p>
      </div>
      <div onEditable="show">
        <span onEditable="hide">hide inside show</span>
        <p>Unspecified in show</p>
      </div>
    </MyComponent>,
    document.getElementById('root')
  );
<div id='root'/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

就像在控制台中看到的那样,以级联的方式分配正确的onEditable值是可行的,但仅渲染show的值无效。遵循代码时,哪种方式有意义。问题是;我不知道该如何解决。

对于我来说,最难的事情是能够渲染一个父组件,当其中一个子组件的onEditable设置为hide时,该父组件的show设置为onEditable

这听起来可能令人困惑,所以我将进一步解释。将hide设置为hide的父组件将此属性级联为其子级(以我希望我的HOC的方式),但是如果下层有子级或子级具有此属性,则他的所有父母也需要渲染,但不是他的兄弟姐妹(因为除非另有说明,否则他们仍然拥有父母的<p onEditable="show">show</p> Unspecified <div onEditable="hide"> <span onEditable="show">show inside hide</span> </div> <div onEditable="show"> <p>Unspecified in show</p> </div> 属性)

因此,我希望示例中具有以下DOM结构:

{{1}}

1 个答案:

答案 0 :(得分:1)

  

“如果设置为隐藏,则不会渲染该子项。”

如果不应该渲染孩子,则不要让它通过。

您还应该告诉MyComponent是否应该显示它,而不管它是子元素,即您应该通过预先计算值将onEditable传递给MyComponent,而不是将相同信息传递给子元素并备份给父母。

这被称为“解除状态”,这与快速失败和早日返回的设计模式/最佳实践以及React依赖(并试图执行)的确定性单向数据流保持一致。


好吧,React从上到下工作,父母实际上为孩子指定了道具。我有99%的把握确保一切都倒退了,您应该根据isVisible={true}告诉孩子isVisible={false}this.props.isEditable。 (或添加classNames /实际上不渲染它们)。

子级可以配置父级的唯一方法是通过回调或通过全局状态管理器(例如redux)将道具重新注入父级。

如果您的孩子正在神奇地获取有关是否应该渲染的信息,则应致电this.props.onMagicallyGotSomeInformation。否则,该状态应该存在于知道此信息的最接近的父级中,并在必要时将其传递/使用。

另一种批评是短路运算符和您使用的语法会使您感到痛苦多于其应有的价值。使用const,if语句和大括号块:)从长远来看,将使您的生活更轻松。

HOC是一个流行语,它只是一个中间层,用于确定应使用哪些道具或将其转发给孩子,我通常会使用cloneElement来定制孩子。孩子们应该没有这样的信息,如果有,您应该通过回调获取信息。