Instead of writing my components inside a class, I'd like to use the function syntax.

Как переопределить componentDidMount, componentWillMount внутри функциональных компонентов?
Возможно ли такое?

const grid = (props) => {
    console.log(props);
    let {skuRules} = props;

    const componentDidMount = () => {
        if(!props.fetched) {
            props.fetchRules();
        }
        console.log('mount it!');
    };
    return(
        
            
                
                
                  
          
    )
}

Aftab Naveed

Ответов: 8

Ответы (8)

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

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

useEffect может использоваться для репликации поведения жизненного цикла, а useState может использоваться для сохранения состояния в функциональном компоненте.

Базовый синтаксис:

useEffect (callbackFunction, [independentProps]) => cleanupFunction

Вы можете реализовать свой вариант использования в хуках вроде

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

useEffect также может возвращать функцию, которая будет запущена при размонтировании компонента. Это можно использовать для отказа от подписки на слушателей, реплицируя поведение componentWillUnmount:

Например: componentWillUnmount

useEffect(() => {
    window.addEventListener('unhandledRejection', handler);
    return () => {
       window.removeEventListener('unhandledRejection', handler);
    }
}, [])

Чтобы сделать useEffect условным для определенных событий, вы можете предоставить ему массив значений для проверки изменений:

Например: componentDidUpdate

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

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

useEffect(() => {
     // action here
}, [props.counter]); // checks for changes in the values in this array

Если вы включаете этот массив, убедитесь, что вы включили все значения из области компонента, которые меняются с течением времени (реквизиты, состояние), или вы можете в конечном итоге ссылаться на значения из предыдущих рендеров.

Есть некоторые тонкости использования useEffect; проверьте API Здесь.


До 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(
        
            
                
                
                  
          
    )
  }
}

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

По документации:

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

useEffect(() => {


});

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

componentDidMount

useEffect(()=>{
   // code here
})

componentWillMount

useEffect(()=>{

   return ()=>{ 
                //code here
              }
})

componentDidUpdate

useEffect(()=>{

    //code here
    // when userName state change it will call     
},[userName])

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

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

A Note from the Author of recompose (acdlite, Oct 25 2018):

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

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

Если вы используете версию React, которая не поддерживает хуки, не беспокойтесь, используйте перекомпоновку(пояс служебных программ React для функциональных компонентов и компонентов более высокого порядка). Вы можете использовать перекомпоновать для присоединения хуков жизненного цикла, состояния, обработчиков и т. Д. к функциональному компоненту.

Вот компонент без рендеринга, который присоединяет методы жизненного цикла через 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);

Вы можете использовать модуль create-response-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 (
            

{this.state.date.toLocaleTimeString()}

) }, componentDidMount:function(){ this.timerId = setInterval(()=>this.setState({date:new Date()}),1000) }, componentWillUnmount:function(){ clearInterval(this.timerId) } }) ReactDOM.render( , document.getElementById('root') )

если вы используете response 16.8, вы можете использовать react Hooks ... React Hooks - это функции, которые позволяют «подключиться» к функциям состояния и жизненного цикла React из функциональных компонентов ... документы

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

Hello

) export default lifecycle(methods)(Channels);

Вы можете создавать свои собственные «методы жизненного цикла», используя хуки для максимальной ностальгии.

Служебные функции:

импорт {useEffect, useRef} из «реакции»;

export const useComponentDidMount = handler => {
  return useEffect (() => {
    обработчик возврата ();
  }, []);
};

export const useComponentDidUpdate = (обработчик, deps) => {
  const isInitialMount = useRef (истина);

  useEffect (() => {
    if (isInitialMount.current) {
      isInitialMount.current = false;

      возвращение;
    }

    обработчик возврата ();
  }, депс);
};

export const useComponentWillUnmount = handler => {
  return useEffect (() => обработчик, []);
};

Использование:

import {
  useComponentDidMount,
  useComponentDidUpdate,
  useComponentWillUnmount
} from "./utils";

export const MyComponent = ({ myProp }) => {
  useComponentDidMount(() => {
    console.log("Component did mount!");
  });

  useComponentDidUpdate(() => {
    console.log("Component did update!");
  });

  useComponentDidUpdate(() => {
    console.log("myProp did update!");
  }, [myProp]);

  useComponentWillUnmount(() => {
    console.log("Component will unmount!");
  });

  return 
Hello world
; };

2022 WebDevInsider