score:1

Accepted answer

This answer will not solve your problem but maybe gives a hint why this is not possible. At first I was surprised why your code does not work, even though I'm not an experienced React developer it seems ok map this.props.children through with React.Children.map and return the desired Component with your HOC. But it did not work.

I tried to debug it a little bit and did some search. I've learned props.children actually contains the elements itself not the instances of components. Even, React.Children.map does not have any effect on this.

Here is a working snippet proves that your problem is not related with the HOC. I've used an array of components instead of mapping through props.children.

class Line1 extends React.Component {
  componentDidMount() {
    setTimeout(this.props.onAnimationEnd, 1000);
  }

  render() {
    return <div>Line 1</div>;
  }
}

class Line2 extends React.Component {
  componentDidMount() {
    setTimeout(this.props.onAnimationEnd, 1000);
  }

  render() {
    return <div>Line 2</div>;
  }
}

class Line3 extends React.Component {
  componentDidMount() {
    setTimeout(this.props.onAnimationEnd, 1000);
  }

  render() {
    return <div>Line 3</div>;
  }
}


const withNotification = handler => Component => props => (
  <Component onAnimationEnd={handler} {...props} />
);

class Sequence extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      pointer: 0
    };

    this.notifyAnimationEnd = this.notifyAnimationEnd.bind(this);

    this.Arr = [ Line1, Line2, Line3 ];
    this.Children = this.Arr.map(Child =>
      withNotification(this.notifyAnimationEnd)(Child)
    );
  }

  notifyAnimationEnd() {
    this.next();
  }

  next() {
    // Clearly, render the next element only if there is, a next element
    if (this.state.pointer >= this.Arr.length - 1) {
      return;
    }

    this.setState({ pointer: this.state.pointer + 1 });
  }

  render() {
    return (
      <div>
        {this.Children.map((Child, i) => {
          if (i <= this.state.pointer) return <Child />;
          return <div>nope</div>;
        })}
      </div>
    );
  }
}



ReactDOM.render(
  <Sequence />,
  document.getElementById("app")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

score:0

You are returning <Child /> instead of Child in Sequence.js render method. Here is my edited copy - codesandbox


Related Query