クラス内にコンポーネントを記述する代わりに、代わりに関数構文を使用したいと思います。
機能コンポーネント内で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>
)
}
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);
Edit:Hooks
の導入により、機能コンポーネントのライフサイクルの種類と状態を実装できるようになりました。現在
フックは、クラスを記述せずに状態およびその他のReact機能を使用できる新しい機能の提案です。それらはv16.8.0の一部としてReactでリリースされます
useEffect
フックを使用してライフサイクル動作を複製でき、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
は、コンポーネントがアンマウントされたときに実行される関数を返すこともできます。これは、リスナーの購読を解除するために使用できます。を使用して、componentWillUnmount
の動作を複製できます。
例:componentWillUnmount
useEffect(() => {
window.addEventListener('unhandledRejection', handler);
return () => {
window.removeEventListener('unhandledRejection', handler);
}
}, [])
値を指定する場合の2番目の引数として、これらの値が次のいずれかの変更である場合、コールバックをトリガーする前に比較されます
例:componentDidUpdate
componentDidUpdate(prevProps, prevState) {
const { counter } = this.props;
if (this.props.counter !== nextProps.counter) {
// some action here
}
}
同等のフック
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>
)
}
}
機能コンポーネントは、追加のロジックを必要とせずにコンポーネントのみをレンダリングする場合に役立ちます。
解決策1:新しいreact HOOKS APIを使用できます。現在React v16.8.0
フックを使用すると、クラスなしでReactの機能をより多く使用できます。フックは、すでに知っているReact概念に対するより直接的なAPIを提供します:props 、状態、コンテキスト、参照、およびlifecycle。フックは、Recomposeで対処されたすべての問題を解決します。
recompose
の著者からのメモ(acdlite、2018年10月25日):
こんにちは!約3年前にRecomposeを作成しました。その約1年後、Reactチームに参加しました。本日、フックの提案を発表しました。 Hooksは、3年前にRecomposeで対処しようとしたすべての問題を解決します。このパッケージのアクティブメンテナンスを中止し(将来のReactリリースとの互換性のためのバグ修正またはパッチを除く)、代わりにフックを使用することを推奨します。 Recomposeを使用した既存のコードは引き続き機能しますが、新しい機能を期待しないでください。
ソリューション2:
フックをサポートせず、心配することのない反応バージョンを使用している場合は、代わりに recompose
(A Reactユーティリティコンポーネントベルトを使用してください。) lifecycle hooks, state, handlers etc
を機能コンポーネントにアタッチするには、recompose
を使用できます。
これは、ライフサイクル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);
React LifeCycleを使用する必要がある場合は、クラスを使用する必要があります。
サンプル:
import React, { Component } from 'react';
class Grid extends Component {
constructor(props){
super(props)
}
componentDidMount () { /* do something */ }
render () {
return <h1>Hello</h1>
}
}
Create-react-classモジュールを利用できます。 公式ドキュメント
もちろん、最初にインストールする必要があります
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')
)
react 16.8を使用している場合は、reactフックを使用できます... Reactフックは、関数コンポーネントからReact状態およびライフサイクル機能を「フック」する機能です... docs
ドキュメントによると:
import React, { useState, useEffect } from 'react'
// Similar to componentDidMount and componentDidUpdate:
useEffect(() => {
});
React documentation を参照してください