代码之家  ›  专栏  ›  技术社区  ›  STO

访问react元素的子元素

  •  2
  • STO  · 技术社区  · 6 年前

    想象一下有React组件

    function List() {
       return (<ul>
                 <li>1</li>
                 <li>2</li>
               </ul>
        );
    }
    

    我想创建一个高阶组件,它可以修改所有 li 节点。

    function makeRed(component) {
        return function(props) {
             const element = React.createElement(component, props);
    
             return React.cloneElement(
                element,
                element.props,
                React.Children.map(
                    element.props.children,
                    ch => React.cloneElement(ch, { 
                            ...ch.props, 
                            style: {
                               backgroundColor: "red"
                            }
                        },                    
                        ch.props.children
                    )
                )
            );
        }
    }
    

    但是。这不管用。孩子们是空的。

    有趣的是,如果我直接创建组件

    ...    
    const element = <ul><li>1</li><li>2</li></ul>;
    ...
    

    问题:如何访问任何React元素的子代和孙代?

    1 回复  |  直到 6 年前
        1
  •  1
  •   hazardous    6 年前

    正如@hamms所指出的,这是一种反模式。有 better ways to implement themes in React 使用普通的旧CSS。

    这么说吧,这里有一个你的用例的工作示例- https://codesandbox.io/s/ymqwyww22z .

    基本上,我所做的是:

    1. 制造 List 基于类的组件。把一个功能组件包装成一个并不太麻烦。

      import React, { Component } from "react";
      
      export default class List extends Component {
        render() {
          return (
            <ul>
              <li>1</li>
              <li>2</li>
            </ul>
          );
        }
      }
      
    2. 实施 render 在动态类中 Red<Component> 首先获取从基本组件的呈现返回的元素树,然后对其进行编辑。

      import React from "react";
      
      export default function makeRed(Component) {
        return class RedComponent extends Component {
          constructor(props) {
            super(props);
      
            RedComponent.displayName = `Red${Component.name}`;
          }
      
          render() {
            let componentElement = super.render();
            let { children, ...rest } = componentElement.props;
            children = React.Children.map(children, child => {
              return React.cloneElement(child, {
                ...child.props,
                style: {
                  backgroundColor: "red"
                }
              });
            });
            return React.cloneElement(componentElement, rest, ...children);
          }
        };
      }
      

    这和 createElement 版本 makeRed ?

    作为 变红 返回HOC,当您在 App 组件,你不给它分配道具。像这样的。。。

    function App() {
      return <RedList />; // no props!
    }
    

    所以在动态组件函数中,使用 createElement公司 要创建新实例, component.props 不要带孩子。自从 列表 创建自己的子级,您需要获取并修改它们,而不是从 props .