React Cookbook
上QQ阅读APP看书,第一时间看更新

How to do it...

It's now time to convert our Header component to a functional component:

  1. First, let's see what the current Header component looks like:
  import React, { Component } from 'react';
import PropTypes from 'prop-types';
import logo from '../../images/logo.svg';

class Header extends Component {
static propTypes = {
title: PropTypes.string.isRequired,
url: PropTypes.string
};

render() {
const {
title = 'Welcome to React',
url = 'http://localhost:3000'
} = this.props;

return (
<header className="App-header">
<a href={url}>
<img src={logo} className="App-logo" alt="logo" />
</a>
<h1 className="App-title">{title}</h1>
</header>
);
}
}

export default Header;
File: src/shared/components/layout/Header.js
  1. The first thing to do is to convert our class component into an arrow function, and with this change, we don't need to import  React.Component anymore. The second part of the migration is to pass the props as parameter in the function instead of getting them from this.props, and the last step is to move our static propTypes as a node of the function. After those changes, our code should look like this:
  import React from 'react';
import PropTypes from 'prop-types';
import logo from '../../images/logo.svg';

// We created a component with a simple arrow function.
const Header = props => {
const {
title = 'Welcome to React',
url = 'http://localhost:3000'
} = props;

return (
<header className="App-header">
<a href={url}>
<img src={logo} className="App-logo" alt="logo" />
</a>
<h1 className="App-title">{title}</h1>
</header>
);
};

// Even with Functional Components we are able to validate our
// PropTypes.

Header.propTypes = {
title: PropTypes.string.isRequired,
url: PropTypes.string
};

export default Header;
File: src/shared/components/layout/Header.js
A functional component is an equivalent to just  having the render method . That's why we only need to return the JSX directly.
  1. After we migrated our Header component, we will migrate the Footer component; this is easier because it does not have props. First, let's see what our Footer component looks like:
  import React, { Component } from 'react';

class Footer extends Component {
render() {
return (
<footer>
&copy; Codejobs {(new Date()).getFullYear()}
</footer>
);
}
}

export default Footer;
File: src/shared/components/layout/Footer.js
  1. Now, as a functional component, it should look like this:
  import React from 'react';

// Since we don't have props, we can directly return our JSX.
const Footer = () => (
<footer>&copy; Codejobs {(new Date()).getFullYear()}</footer>
);

export default Footer;
File: src/shared/components/layout/Footer.js
In this case, as you can see, we need to create an arrow function without parameters (because we don't have any props) and directly return the JSX we need to render.
  1. Converting the Content component to a functional component:
  import React, { Component } from 'react';
import PropTypes from 'prop-types';

class Content extends Component {
static propTypes = {
children: PropTypes.element.isRequired
};

render() {
const { children } = this.props;

return (
<main>
{children}
</main>
);
}
}

export default Content;
File: src/shared/components/layout/Content.js
  1. This component is similar to our Header component. We need to pass the props as parameters and keep our propTypes:
  import React from 'react';
import PropTypes from 'prop-types';

const Content = props => {
const { children } = props;

return (
<main>
{children}
</main>
);
};

Content.propTypes = {
children: PropTypes.element.isRequired
};

export default Content;
File : src/shared/components/layout/Content.js