Метод жизненного цикла ReactJS внутри функционального компонента

Вместо того чтобы писать свои компоненты внутри класса, я хотел бы использовать вместо этого функциональный синтаксис.

Как переопределить 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>  
    )
}

Ответы

Ответ 1

Вы можете использовать real-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

Редактировать: С введением Hooks стало возможным реализовать как поведение, так и состояние жизненного цикла в функциональном компоненте. В настоящее время

Хуки - это новое предложение функций, которое позволяет вам использовать состояние и другие функции React без написания класса. Они выпущены в React как часть v16.8.0

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);
    }
}, [])

В качестве второго аргумента, если вы предоставляете значения, они будут сравниваться перед запуском обратного вызова, если это какое-либо изменение в любом из следующих

Например: componentDidUpdate

componentDidUpdate(prevProps, prevState) {
     const { counter } = this.props;
     if (this.props.counter !== nextProps.counter) {
      // some action here
     }
}

Эквивалент крючков

useEffect(() => {
     // action here
}, [props.counter]);

До версии 16.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>  
    )
  }
}

Функциональные компоненты полезны, когда вы хотите визуализировать ваш компонент без дополнительной логики.

Ответ 3

Решение первое: вы можете использовать новый реагирующий HOOKS API. В настоящее время в React v16.8.0

Хуки позволяют вам использовать больше возможностей Reacts без классов. Хуки предоставляют более прямой API для уже знакомых вам понятий React: реквизиты, состояние, контекст, ссылки и жизненный цикл. Hooks решает все проблемы, решаемые с помощью Recompose.

Примечание автора recompose (acdlite, 25 октября 2018 г.):

Привет! Я создал Recompose около трех лет назад. Примерно через год я присоединился к команде React. Сегодня мы объявили о предложении для крючков. Hooks решает все проблемы, которые я пытался решить с помощью Recompose три года назад, и многое другое. Я буду прекращать активное обслуживание этого пакета (за исключением, возможно, исправлений или исправлений для совместимости с будущими выпусками React) и рекомендую вместо этого использовать Hooks. Ваш существующий код с Recompose все еще будет работать, только не ожидайте каких-либо новых функций.

Решение второе:

Если вы используете версию реагирования, которая не поддерживает хуки, не беспокойтесь, вместо этого используйте 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

Если вам нужно использовать React LifeCycle, вам нужно использовать Class.

Образец:

import React, { Component } from 'react';

class Grid extends Component {

 constructor(props){
  super(props)
 }

 componentDidMount () { /* do something */ }

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

}

Ответ 5

Вы можете использовать модуль create-реагировать-класса. Официальная документация

Конечно, вы должны сначала установить его

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

если вы используете реагирование 16.8, вы можете использовать реагирующие зацепки... Реактивные зацепки - это функции, которые позволяют вам "зацепиться" за состояние React и функции жизненного цикла из компонентов функций... документы

Ответ 7

Согласно документации:

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

useEffect(() => {


});

см. React документацию