首先让我说这个例子很简单,可以用React.cloneElement解决。但我想要更多的自由,项目将更加复杂,所以我想找到一个解决方案。 我也想了解我所缺少的内容:/
我希望能够使用props和方法(因此HOC)扩充Parent组件的子组件。它将从这里开始:
<Parent>
<aChild />
<anotherChild />
<yetAnotherChild />
</Parent>
到目前为止,这是Parent组件(在我的项目中称为Sequence):
import React, { Component } from 'react';
const withNotification = handler => Component => props => (
<Component onAnimationEnd={handler} {...props} />
);
class Sequence extends Component {
constructor(props) {
super(props);
this.state = {
pointer: 0,
};
this.notifyAnimationEnd = this.notifyAnimationEnd.bind(this);
this.Children = React.Children.map(this.props.children, Child =>
withNotification(this.notifyAnimationEnd)(Child)
);
}
notifyAnimationEnd() {
// do stuff
}
render() {
return (
<div>
{this.Children.map((Child, i) => {
if (i <= this.state.pointer) return <Child />;
return <div>nope</div>;
})}
</div>
);
}
}
export default Sequence;
我收到以下错误:
你可以在这里玩代码:https://codesandbox.io/s/6w1n5wor9w
感谢您的任何帮助!
这个答案不会解决你的问题,但可能会暗示为什么这是不可能的。起初我很惊讶为什么你的代码不起作用,即使我不是一个经验丰富的React开发人员,似乎可以通过this.props.children
映射React.Children.map
并使用你的HOC返回所需的组件。但它没有用。
我尝试调试它和did some search。我已经学会了props.children
实际上包含元素本身而不是组件的实例。甚至,React.Children.map
对此没有任何影响。
这是一个工作片段,证明您的问题与HOC无关。我使用了一系列组件而不是映射到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>
你在Sequence.js渲染方法中返回<Child />
而不是Child
。这是我编辑的副本 - codesandbox