Skip to content

Commit

Permalink
Use Function Components and Hooks (#1797)
Browse files Browse the repository at this point in the history
* Use function component and hooks

* update docs
  • Loading branch information
piglovesyou authored Nov 11, 2019
1 parent 7408308 commit 857dfef
Show file tree
Hide file tree
Showing 21 changed files with 530 additions and 575 deletions.
24 changes: 16 additions & 8 deletions docs/data-fetching.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,22 @@ React components as follows:
#### React Component

```js
class Post extends React.Component {
static contextTypes = { fetch: PropTypes.func.isRequired };
handleDelete = (event) => {
event.preventDefault();
const id = event.target.dataset['id'];
this.context.fetch(`/api/posts/${id}`, { method: 'DELETE' }).then(...);
};
render() { ... }
import {useContext} from 'react';
import ApplicationContext from '../ApplicationContext';

function Post() {
const {context} = useContext(ApplicationContext);
return (
<div>
...
<a onClick={(event) => {
event.preventDefault();
const id = event.target.dataset['id'];
// Use context.fetch to make it work in both server-side and client-side
context.fetch(`/api/posts/${id}`, { method: 'DELETE' }).then(...);
}}>Delete</a>
</div>
);
}
```

Expand Down
16 changes: 6 additions & 10 deletions docs/react-style-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,11 @@ Navigation.propTypes = { items: PropTypes.array.isRequired };
// Navigation.js
import React from 'react';
import PropTypes from 'prop-types';
import withStyles from 'isomorphic-style-loader/withStyles';
import useStyles from 'isomorphic-style-loader/useStyles';
import s from './Navigation.scss';

function Navigation() {
export default function Navigation() {
useStyles(s);
return (
<nav className={`${s.root} ${this.props.className}`}>
<ul className={s.items}>
Expand All @@ -150,8 +151,6 @@ function Navigation() {
}

Navigation.propTypes = { className: PropTypes.string };

export default withStyles(Navigation, s);
```

### Use higher-order components
Expand Down Expand Up @@ -205,14 +204,11 @@ export default withViewport;

```js
// MyComponent.js
import React from 'react';
import withViewport from './withViewport';

class MyComponent {
render() {
let { width, height } = this.props.viewport;
return <div>{`Viewport: ${width}x${height}`}</div>;
}
function MyComponent(props) {
const { width, height } = props.viewport;
return <div>{`Viewport: ${width}x${height}`}</div>;
}

export default withViewport(MyComponent);
Expand Down
58 changes: 28 additions & 30 deletions docs/recipes/how-to-implement-routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,38 +157,36 @@ In order to trigger client-side navigation without causing full-page refresh, yo
`history.push()` method, for example:

```js
import React from 'react';
import history from '../history';

class App extends React.Component {
transition = event => {
event.preventDefault();
history.push({
pathname: event.currentTarget.pathname,
search: event.currentTarget.search,
});
};
render() {
return (
<ul>
<li>
<a href="/" onClick={this.transition}>
Home
</a>
</li>
<li>
<a href="/one" onClick={this.transition}>
One
</a>
</li>
<li>
<a href="/two" onClick={this.transition}>
Two
</a>
</li>
</ul>
);
}
function transition(event) {
event.preventDefault();
history.push({
pathname: event.currentTarget.pathname,
search: event.currentTarget.search,
});
}

function App() {
return (
<ul>
<li>
<a href="/" onClick={transition}>
Home
</a>
</li>
<li>
<a href="/one" onClick={transition}>
One
</a>
</li>
<li>
<a href="/two" onClick={transition}>
Two
</a>
</li>
</ul>
);
}
```

Expand Down
25 changes: 10 additions & 15 deletions docs/recipes/how-to-integrate-disqus.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,22 +65,17 @@ export default DisqusThread;
#### `MyComponent.js`

```js
import React from 'react';
import DisqusThread from './DisqusThread.js';

class MyComponent extends React.Component {
render() {
return (
<div>
<DisqusThread
id="e94d73ff-fd92-467d-b643-c86889f4b8be"
title="How to integrate Disqus into ReactJS App"
path="/blog/123-disquss-integration"
/>
</div>
);
}
export default function MyComponent() {
return (
<div>
<DisqusThread
id="e94d73ff-fd92-467d-b643-c86889f4b8be"
title="How to integrate Disqus into ReactJS App"
path="/blog/123-disquss-integration"
/>
</div>
);
}

export default MyComponent;
```
53 changes: 23 additions & 30 deletions src/components/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,6 @@ import PropTypes from 'prop-types';
import StyleContext from 'isomorphic-style-loader/StyleContext';
import ApplicationContext from './ApplicationContext';

const ContextType = {
// Universal HTTP client
fetch: PropTypes.func.isRequired,
pathname: PropTypes.string.isRequired,
query: PropTypes.object,
};

/**
* The top-level React component setting context (global) variables
* that can be accessed from all the child components.
Expand All @@ -34,36 +27,36 @@ const ContextType = {
* };
*
* ReactDOM.render(
* <App context={context}>
* <App context={context} insertCss={() => {}}>
* <Layout>
* <LandingPage />
* </Layout>
* </App>,
* container,
* );
*/
class App extends React.PureComponent {
static propTypes = {
// Enables critical path CSS rendering
// https://github.com/kriasoft/isomorphic-style-loader
insertCss: PropTypes.func.isRequired,
context: PropTypes.shape(ContextType).isRequired,
children: PropTypes.element.isRequired,
};

render() {
const { context, insertCss } = this.props;

// NOTE: If you need to add or modify header, footer etc. of the app,
// please do that inside the Layout component.
return (
<StyleContext.Provider value={{ insertCss }}>
<ApplicationContext.Provider value={{ context }}>
{React.Children.only(this.props.children)}
</ApplicationContext.Provider>
</StyleContext.Provider>
);
}
export default function App({ context, insertCss, children }) {
// NOTE: If you need to add or modify header, footer etc. of the app,
// please do that inside the Layout component.
return (
<StyleContext.Provider value={{ insertCss }}>
<ApplicationContext.Provider value={{ context }}>
{React.Children.only(children)}
</ApplicationContext.Provider>
</StyleContext.Provider>
);
}

export default App;
App.propTypes = {
// Enables critical path CSS rendering
// https://github.com/kriasoft/isomorphic-style-loader
insertCss: PropTypes.func.isRequired,
context: PropTypes.shape({
// Universal HTTP client
fetch: PropTypes.func.isRequired,
pathname: PropTypes.string.isRequired,
query: PropTypes.object,
}).isRequired,
children: PropTypes.element.isRequired,
};
45 changes: 21 additions & 24 deletions src/components/Feedback/Feedback.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,29 @@
* LICENSE.txt file in the root directory of this source tree.
*/

import useStyles from 'isomorphic-style-loader/useStyles';
import React from 'react';
import withStyles from 'isomorphic-style-loader/withStyles';
import s from './Feedback.css';

class Feedback extends React.Component {
render() {
return (
<div className={s.root}>
<div className={s.container}>
<a
className={s.link}
href="https://gitter.im/kriasoft/react-starter-kit"
>
Ask a question
</a>
<span className={s.spacer}>|</span>
<a
className={s.link}
href="https://github.com/kriasoft/react-starter-kit/issues/new"
>
Report an issue
</a>
</div>
export default function Feedback() {
useStyles(s);
return (
<div className={s.root}>
<div className={s.container}>
<a
className={s.link}
href="https://gitter.im/kriasoft/react-starter-kit"
>
Ask a question
</a>
<span className={s.spacer}>|</span>
<a
className={s.link}
href="https://github.com/kriasoft/react-starter-kit/issues/new"
>
Report an issue
</a>
</div>
);
}
</div>
);
}

export default withStyles(s)(Feedback);
54 changes: 26 additions & 28 deletions src/components/Footer/Footer.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,35 @@
* LICENSE.txt file in the root directory of this source tree.
*/

import useStyles from 'isomorphic-style-loader/useStyles';
import React from 'react';
import withStyles from 'isomorphic-style-loader/withStyles';
import s from './Footer.css';
import Link from '../Link';

class Footer extends React.Component {
render() {
return (
<div className={s.root}>
<div className={s.container}>
<span className={s.text}>© Your Company</span>
<span className={s.spacer}>·</span>
<Link className={s.link} to="/">
Home
</Link>
<span className={s.spacer}>·</span>
<Link className={s.link} to="/admin">
Admin
</Link>
<span className={s.spacer}>·</span>
<Link className={s.link} to="/privacy">
Privacy
</Link>
<span className={s.spacer}>·</span>
<Link className={s.link} to="/not-found">
Not Found
</Link>
</div>
export default function Footer() {
useStyles(s);

return (
<div className={s.root}>
<div className={s.container}>
<span className={s.text}>© Your Company</span>
<span className={s.spacer}>·</span>
<Link className={s.link} to="/">
Home
</Link>
<span className={s.spacer}>·</span>
<Link className={s.link} to="/admin">
Admin
</Link>
<span className={s.spacer}>·</span>
<Link className={s.link} to="/privacy">
Privacy
</Link>
<span className={s.spacer}>·</span>
<Link className={s.link} to="/not-found">
Not Found
</Link>
</div>
);
}
</div>
);
}

export default withStyles(s)(Footer);
Loading

0 comments on commit 857dfef

Please sign in to comment.