Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Function Components and Hooks #1797

Merged
merged 2 commits into from
Nov 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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