简体   繁体   English

如何在渲染前将属性添加到传递给props-的HTML标签中?

[英]How to add attribute to HTML tag passed in props- before render?

I have some code that takes an array of JSX as props. 我有一些将JSX数组作为道具的代码。 The component is supposed to ensure that all JSX is rendered in the order they appear in the array. 该组件应确保所有JSX均按照它们在数组中出现的顺序进行渲染。 In order to do this, all of my components have an optional onLoad function they can take as a prop. 为了做到这一点,我所有的组件都有一个可选的onLoad函数,它们可以作为道具。 When I initially create the array of JSX in a parent component, this function isn't being added, so that I don't have to write the same function in all of these different parent classes. 当我最初在父组件中创建JSX数组时,并未添加此函数,因此不必在所有这些不同的父类中编写相同的函数。 So I pass them to my component that handles the load order, but it needs a way to add the onLoad attribute to everything in the array. 因此,我将它们传递给处理加载顺序的组件,但它需要一种将onLoad属性添加到数组中所有内容的方法。

I have tried mapping through the array and using child.setAttribute on each element, but I get the error: setAttribute is not a function 我尝试通过数组映射并在每个元素上使用child.setAttribute ,但出现错误: setAttribute is not a function

I have also tried child.onLoad = this.childDidLoad which resulted in the error: Cannot add property onLoad, object is not extensible 我也尝试过child.onLoad = this.childDidLoad导致错误: Cannot add property onLoad, object is not extensible

I have tried spreading, which you should see below. 我已经尝试过传播,您应该在下面看到。 This doesn't throw errors, but appears to never add the attribute, as that section of code is never reached. 这不会引发错误,但是似乎永远不会添加属性,因为永远不会到达该部分代码。

class StandardPage extends Component {
  static propTypes = {
    children: PropTypes.array.isRequired, // All child components to render
  };

  state = {
    childrenLoaded: 0, // Number of children loaded
  };

  /**
   * When this method is called, a child has updated.
   * Take previous value of number of children loaded, and add one.
   * Store as new value in state
   */
  childDidLoad() {
    const {childrenLoaded} = this.state;

    this.setState({
      childrenLoaded: childrenLoaded + 1,
    });
  }

  /**
   * Slice children array to only return those that have loaded, plus one.
   * THIS CONTAINS THE PROBLEM!!!
   * @return {array} JSX array
   */
  getLoaded() {
    const {childrenLoaded} = this.state;
    const {children} = this.props;

    this.childDidLoad = this.childDidLoad.bind(this);
    const loaded = children.slice(0, childrenLoaded + 1);

    return loaded.map((child) => {
      return {
        ...child, // THIS IS THE PROBLEM SPOT
        onLoad: this.childDidLoad,
      };
    });
  }

  /**
   * Visual component
   * @return {jsx}
   */
  render() {
    const components = this.getLoaded();

    return (
      <div className="page">
        <Nav>
          {components}
        </Nav>
      </div>
    );
  }
}

example use: 示例使用:

class ExamplePage extends Component {
  state = {
    children: [
      <Section
            key="origin"
            restEndpoint="origin"
            id={originID}
            bgColor={(isYellow) ? 'yellow' : 'white'}
            txtJustify={true}
          />,
      <Section
            key="funFacts"
            restEndpoint="funfacts"
            id={funFactID}
            bgColor={(isYellow) ? 'yellow' : 'white'}
            txtJustify={true}
          />
    ],
  };

  /**
   * Visual component
   * @return {jsx}
   */
  render() {
    const {children} = this.state;

    return (
      <StandardPage children={children} />
    );
  }
}

Right now, the first child component gets displayed, and no others, as the childDidLoad method is never getting called. 现在,将显示第一个子组件,而不会显示其他子组件,因为永远不会调用childDidLoad方法。

return loaded.map((child) => {
    return React.cloneElement(child, { onLoad: this.childDidLoad });
});

This may work for you to pass the method as a prop to your Component. 这可能对您有用,可以将方法作为道具传递给组件。 I gonna setup a test on my local machine for further investigations if it doesnt help. 如果没有帮助,我将在本地计算机上进行测试以进行进一步的调查。 greetz 格尔茨

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM