convert from React component to using one hooks

Viewed 81

I am learning React hooks and wanted to convert a relatively simple component to the one using hooks. The component is called FadeIn and it wraps the children component to become visible (using CSS and opacity) in whatever transitionDuration is passed from the parent component. Below is the working code of my component:

import React, { Component } from 'react';
import PropTypes from 'prop-types';

export class FadeIn extends Component {
  constructor(props) {
    super(props);
    this.makeVisible = this.makeVisible.bind(this);
    this.state = { opacity: 0.01 };
  }

  componentDidMount() {
    this.makeVisible();
  }

  makeVisible() {
    this.setState({ opacity: 1 });
  }

  render() {
    const { children, transitionDuration } = this.props;
    const { opacity } = this.state;
    return (
      <div
        style={{
          transition: `opacity ${transitionDuration}ms ease-in`,
          opacity,
        }}
      >
        {children}
      </div>
    );
  }
}


FadeIn.defaultProps = {
  transitionDuration: 600,
};

FadeIn.propTypes = {
  children: PropTypes.oneOfType([
    PropTypes.arrayOf(PropTypes.node),
    PropTypes.node,
  ]).isRequired,
  transitionDuration: PropTypes.number,
};

Here's what my hooks component looks like:

import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';

export const FadeIn = (props) => {
  const [opacity, makeVisible] = useState(0.01);
  const [children, setChildren] = useState(props);
  const [transitionDuration, setTransitionDuration] = useState(props);

  useEffect(() => {
    makeVisible(1);
    setChildren(props);
    setTransitionDuration(props);
  }, [props])



  return (
    <div
      style={{
        transition: `opacity ${transitionDuration}ms ease-in`,
        opacity,
      }}
    >
      {children}
    </div>
  );
}
// }


FadeIn.defaultProps = {
  transitionDuration: 600,
};

FadeIn.propTypes = {
  children: PropTypes.oneOfType([
    PropTypes.arrayOf(PropTypes.node),
    PropTypes.node,
  ]).isRequired,
  transitionDuration: PropTypes.number,
};

I get quiet a stange error related to

Invariant Violation: Objects are not valid as a React child (found: object with keys {children, transitionDuration}). If you meant to render a collection of children, use an array instead.

what is the issue here?

1 Answers

You are setting props object in your state. You need to get children array from props.children

setChildren(props);

to

setChildren(props.children);

Keep in mind that it is completely unnecessary as you can just render the children by accessing props.children without saving them in the state

return (
    <div
      style={{
        transition: `opacity ${transitionDuration}ms ease-in`,
        opacity,
      }}
    >
      {props.children}

    </div>
);

You also need to change

setTransitionDuration(props);

to

setTransitionDuration(props.transitionDuration);
Related