我不想在类中编写我的组件,而是想使用函数语法。
如何覆盖功能组件中的componentDidMount
,componentWillMount
?
它甚至可能吗?
const grid = (props) => {
console.log(props);
let {skuRules} = props;
const componentDidMount = () => {
if(!props.fetched) {
props.fetchRules();
}
console.log('mount it!');
};
return(
<Content title="Promotions" breadcrumbs={breadcrumbs} fetched={skuRules.fetched}>
<Box title="Sku Promotion">
<ActionButtons buttons={actionButtons} />
<SkuRuleGrid
data={skuRules.payload}
fetch={props.fetchSkuRules}
/>
</Box>
</Content>
)
}
答案 0 :(得分:49)
编辑:引入Hooks
可以实现生命周期类型的行为以及功能组件中的状态。目前
Hooks是一项新功能提案,可让您使用状态和其他 无需编写课程即可实现功能。它们作为 v16.8.0
的一部分在React中发布
useEffect
hook可用于复制生命周期行为,useState
可用于在功能组件中存储状态。
您可以在像
这样的钩子中实现您的用例const grid = (props) => {
console.log(props);
let {skuRules} = props;
useEffect(() => {
if(!props.fetched) {
props.fetchRules();
}
console.log('mount it!');
}, []); // passing an empty array as second argument triggers the callback in useEffect only after the initial render thus replicating `componentDidMount` lifecycle behaviour
return(
<Content title="Promotions" breadcrumbs={breadcrumbs} fetched={skuRules.fetched}>
<Box title="Sku Promotion">
<ActionButtons buttons={actionButtons} />
<SkuRuleGrid
data={skuRules.payload}
fetch={props.fetchSkuRules}
/>
</Box>
</Content>
)
}
useEffect
也可以返回在卸载组件时运行的函数。这可以用于取消订阅听众。 An可用于复制componentWillUnmount
行为
例如:componentWillUnmount
useEffect(() => {
window.addEventListener('unhandledRejection', handler);
return () => {
window.removeEventListener('unhandledRejection', handler);
}
}, [])
作为第二个参数,如果你提供值,那么这些将在触发回调之前进行比较,如果这些是以下任何一个的任何变化
例如:componentDidUpdate
componentDidUpdate(prevProps, prevState) {
const { counter } = this.props;
if (this.props.counter !== nextProps.counter) {
// some action here
}
}
Hooks Equivalent
useEffect(() => {
// action here
}, [props.counter]);
在v16.7.0之前
功能组件的属性是他们无法访问Reacts生命周期函数或this
关键字。如果要使用生命周期功能,则需要扩展React.Component
类。
class Grid extends React.Component {
constructor(props) {
super(props)
}
componentDidMount () {
if(!this.props.fetched) {
this.props.fetchRules();
}
console.log('mount it!');
}
render() {
return(
<Content title="Promotions" breadcrumbs={breadcrumbs} fetched={skuRules.fetched}>
<Box title="Sku Promotion">
<ActionButtons buttons={actionButtons} />
<SkuRuleGrid
data={skuRules.payload}
fetch={props.fetchSkuRules}
/>
</Box>
</Content>
)
}
}
当您只想渲染Component而不需要额外的逻辑时,功能组件非常有用。
答案 1 :(得分:43)
您可以使用react-pure-lifecycle向功能组件添加生命周期功能。
示例:
import React, { Component } from 'react';
import lifecycle from 'react-pure-lifecycle';
const methods = {
componentDidMount(props) {
console.log('I mounted! Here are my props: ', props);
}
};
const Channels = props => (
<h1>Hello</h1>
)
export default lifecycle(methods)(Channels);
答案 2 :(得分:8)
您可以使用hooks来制作自己的“生命周期方法”,以最大程度地怀旧。
实用程序功能
:import { useEffect, useRef } from "react";
export const componentDidMount = handler => {
return useEffect(() => {
return handler();
}, []);
};
export const componentDidUpdate = (handler, deps) => {
const isInitialMount = useRef(true);
useEffect(() => {
if (isInitialMount.current) {
isInitialMount.current = false;
return;
}
return handler();
}, deps);
};
用法:
import { componentDidMount, componentDidUpdate } from "./utils";
export const MyComponent = ({ myProp }) => {
componentDidMount(() => {
console.log("Component did mount!");
});
componentDidUpdate(() => {
console.log("Component did update!");
});
componentDidUpdate(() => {
console.log("myProp did update!");
}, [myProp]);
};
答案 3 :(得分:7)
解决方案一: 您可以使用新的react HOOKS API。当前在 React v16.8.0
中钩子使您无需类即可使用React的更多功能。 挂钩为您已经知道的React概念提供了更直接的API:道具,状态,上下文,引用和生命周期。 Hooks解决了Recompose解决的所有问题。
recompose
作者的注释(acdlite,2018年10月25日):
嗨!我大约在三年前创建了Recompose。大约一年后 我加入了React团队。今天,我们宣布了一项 钩子。挂钩解决了我试图解决的所有问题 三年前重新组合,最重要的是。我会 停止对此软件包的主动维护(可能不包括 与未来的React版本兼容的错误修正或补丁),以及 建议人们改用挂钩。您现有的代码与 重新组合仍然可以使用,只是不要期待任何新功能。
解决方案二:
如果您使用的React版本不支持钩子,请不用担心,请改用recompose
(React实用程序带,用于功能组件和高阶组件。)。您可以使用recompose
将lifecycle hooks, state, handlers etc
附加到功能组件上。
这是一个无需渲染的组件,可通过生命周期HOC(通过重新组合)附加生命周期方法。
// taken from https://gist.github.com/tsnieman/056af4bb9e87748c514d#file-auth-js-L33
function RenderlessComponent() {
return null;
}
export default lifecycle({
componentDidMount() {
const { checkIfAuthed } = this.props;
// Do they have an active session? ("Remember me")
checkIfAuthed();
},
componentWillReceiveProps(nextProps) {
const {
loadUser,
} = this.props;
// Various 'indicators'..
const becameAuthed = (!(this.props.auth) && nextProps.auth);
const isCurrentUser = (this.props.currentUser !== null);
if (becameAuthed) {
loadUser(nextProps.auth.uid);
}
const shouldSetCurrentUser = (!isCurrentUser && nextProps.auth);
if (shouldSetCurrentUser) {
const currentUser = nextProps.users[nextProps.auth.uid];
if (currentUser) {
this.props.setCurrentUser({
'id': nextProps.auth.uid,
...currentUser,
});
}
}
}
})(RenderlessComponent);
答案 4 :(得分:3)
如果您需要使用React LifeCycle,则需要使用Class。
样品:
include('/lib/Vendor/autoload.php');
use Twilio\Rest\Client;
$sid = "";
$token = "";
$client = new Client($sid,$token);
foreach ($client->incomingPhoneNumbers->read() as $number) {
echo $number->phoneNumber;
}
答案 5 :(得分:0)
您可以使用create-react-class模块。 Official documentation
当然您必须先安装它
npm install create-react-class
这是一个可行的例子
import React from "react";
import ReactDOM from "react-dom"
let createReactClass = require('create-react-class')
let Clock = createReactClass({
getInitialState:function(){
return {date:new Date()}
},
render:function(){
return (
<h1>{this.state.date.toLocaleTimeString()}</h1>
)
},
componentDidMount:function(){
this.timerId = setInterval(()=>this.setState({date:new Date()}),1000)
},
componentWillUnmount:function(){
clearInterval(this.timerId)
}
})
ReactDOM.render(
<Clock/>,
document.getElementById('root')
)
答案 6 :(得分:0)
如果您使用react 16.8,则可以使用react Hooks ... React Hooks是使您能够“挂钩”功能组件中的React状态和生命周期功能的函数... docs
答案 7 :(得分:0)
根据文档:
import React, { useState, useEffect } from 'react'
// Similar to componentDidMount and componentDidUpdate:
useEffect(() => {
});