让我开始说,这个示例非常简单,可以使用React.cloneElement解决。但是我希望有更多的自由,项目会更加复杂,所以我想找到一个解决方案。
我也想了解我所缺少的:/
我希望能够使用道具和方法来扩充Parent组件的子代(因此称为HOC)。从这里开始:
<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
谢谢您的帮助!
答案 0 :(得分:1)
此答案不会解决您的问题,但可能会提示为什么这不可能。起初,我感到惊讶的是,即使我不是经验丰富的React开发人员,您的代码也无法正常工作,看来this.props.children
和React.Children.map
可以很好地映射,并通过HOC返回所需的Component。但这没有用。
我尝试调试一下,然后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>
答案 1 :(得分:0)
您将在Sequence.js渲染方法中返回$ django-admin version
1.11.14
而不是<Child />
。这是我编辑过的副本-codesandbox