web-dev-qa-db-ja.com

機能コンポーネント内のReactJSライフサイクルメソッド

クラス内にコンポーネントを記述する代わりに、代わりに関数構文を使用したいと思います。

機能コンポーネント内でcomponentDidMountcomponentWillMountをオーバーライドするにはどうすればよいですか?
それも可能ですか?

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>  
    )
}
55
Aftab Naveed

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);
53
Yohann

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>  
    )
  }
}

機能コンポーネントは、追加のロジックを必要とせずにコンポーネントのみをレンダリングする場合に役立ちます。

62
Shubham Khatri

解決策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);
8
Shivam

React LifeCycleを使用する必要がある場合は、クラスを使用する必要があります。

サンプル:

import React, { Component } from 'react';

class Grid extends Component {

 constructor(props){
  super(props)
 }

 componentDidMount () { /* do something */ }

 render () { 
   return <h1>Hello</h1>
 }

}
2

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')
)
0
Chandan Purohit

react 16.8を使用している場合は、reactフックを使用できます... Reactフックは、関数コンポーネントからReact状態およびライフサイクル機能を「フック」する機能です... docs

0
WAEX

ドキュメントによると:

import React, { useState, useEffect } from 'react'
// Similar to componentDidMount and componentDidUpdate:

useEffect(() => {


});

React documentation を参照してください

0
DevB2F