我正在阅读不要突变原始组件的部分。使用此链接中的合成。
https://reactjs.org/docs/higher-order-components.html
然后,我回顾了我正在尝试构建的项目。从较高的层面来看,这就是我的代码:class Wrapper extends Component {
constructor(props) {
this.wrappedComponent = props.wrappedComponent;
}
async componentWillAppear(cb) {
await this.wrappedComponent.prototype.fetchAllData();
/* use Greensock library to do some really fancy animation on the wrapper <Animated.div> */
this.wrappedComponent.prototype.animateContent();
cb();
}
render() {
<Animated.div>
<this.wrappedComponent {...this.props} />
</Animated.div>
}
}
class Home extends Component {
async fetchAllData(){
const [r1,r2] = await Promise.All([
fetch('http://project-api.com/endpoint1'),
fetch('http://project-api.com/endpoint2')
]);
this.setState({r1,r2});
}
animateContent(){
/* Use the GreenSock library to do fancy animation in the contents of <div id="result"> */
}
render() {
if(!this.state)
return <div>Loading...</div>;
return (
<div id="result">
{this.state.r1.contentHTML}
</div>
);
}
}
export default class App extends Component {
render() {
return <Wrapper wrappedComponent={Home} />;
}
}
我的问题是:
Wrapper.componentWillAppear()
中,我触发了像this.wrappedComponent.prototype.<methodname>
这样的对象方法。这些对象方法可以设置它自己的状态或为渲染函数中的html内容设置动画。这被视为改变原始组件?Home.fetchAllData(){then set the state()}
),更新视图(Home.render()
),运行一些通用动画函数(Wrapper.componentWillAppear(){this.animateFunctionOfSomeKind()}
),然后运行特定的动画对自己(Home.animateContent()
)。那么使用抽象方法继承可能更适合我想做的事情吗?答案 0 :(得分:1)
我实际上可能会编写一个实际的高阶组件。而不仅仅是一个采用prop作为组件的组件(这是你在你的例子中所做的)。主要是因为我认为你实现它的方式有点像代码气味/反模式。
也许这样的事情。
class MyComponent extends React.Component {
constructor() {
super();
this.animateContent = this.animateContent.bind(this);
}
componentWillReceiveProps(nextProps) {
if (this.props.r1 !== nextProps.r1) {
this.animateContent();
}
}
componentDidMount() {
// do your fetching and state setting here
}
animateContent() {
// do something
}
render() {
if(!this.props.r1) {
return <div>Loading...</div>;
}
return (
<div id="result">
{this.props.r1.title}
</div>
);
}
}
const myHOC = asyncFn => WrappedComponent => {
return class EnhancedComponent extends React.Component {
async componentDidMount(){
const [r1, r2] = await asyncFn();
this.setState({ r1, r2 })
this.animateContent();
}
animateContent = () => {
// do some animating for the wrapper.
}
render() {
return (<WrappedComponent {...this.props} {...this.state} />)
}
}
}
const anAsyncExample = async () => {
const result = await fetch("https://jsonplaceholder.typicode.com/posts");
return await result.json();
}
const MyEnhancedComponent = myHOC(anAsyncExample)(MyComponent);
这是一个有效的JSFiddle,所以你可以看到它正在使用中: https://jsfiddle.net/patrickgordon/69z2wepo/96520/
基本上我在这里完成的是创建一个HOC(只是一个函数),它接受一个异步函数并返回另一个函数,它包含一个组件。它将调用该函数并将第一个和第二个结果分配给state,然后将其作为props传递给包装组件。它遵循本文的原则:https://medium.com/@franleplant/react-higher-order-components-in-depth-cf9032ee6c3e