react: start using Hooks!

This commit is contained in:
haishanh 2018-10-30 15:16:42 +08:00
parent 464a26e298
commit 58d21fc3d9
8 changed files with 94 additions and 141 deletions

View file

@ -22,7 +22,7 @@
"@babel/plugin-proposal-do-expressions"
],
"env": {
"development": {
"//development": {
"plugins": [
"react-hot-loader/babel"
]

View file

@ -39,8 +39,8 @@
"memoize-one": "^4.0.2",
"modern-normalize": "^0.5.0",
"prop-types": "^15.5.10",
"react": "^16.6.0",
"react-dom": "^16.6.0",
"react": "^16.7.0-alpha.0",
"react-dom": "^16.7.0-alpha.0",
"react-modal": "^3.6.1",
"react-redux": "^6.0.0-alpha.2a2f108",
"react-router-dom": "4.4.0-beta.4",

View file

@ -8,10 +8,12 @@ import Root from './components/Root';
Modal.setAppElement('#app');
// use async React
const root = ReactDOM.unstable_createRoot(document.getElementById('app'));
const root = ReactDOM.createRoot(document.getElementById('app'));
root.render(<Root />);
// const render = (Component, props = {}) => {
// ReactDOM.render(<Component {...props} />, document.getElementById('app'));
// };
// render(Root, props);
console.log('Checkout the repo: https://github.com/haishanh/yacd');

View file

@ -1,32 +1,22 @@
import React, { Component } from 'react';
// import PropTypes from 'prop-types';
import React from 'react';
import ContentHeader from 'c/ContentHeader';
import TrafficChart from 'c/TrafficChart';
import TrafficNow from 'c/TrafficNow';
import s0 from 'c/Home.module.scss';
class Home extends Component {
// static propTypes = {
// match: PropTypes.object
// };
render() {
// const { match } = this.props;
return (
<div>
<ContentHeader title="Overview" />
<div className={s0.root}>
<div>
<TrafficNow />
</div>
<div className={s0.chart}>
<TrafficChart />
</div>
export default function Home() {
return (
<div>
<ContentHeader title="Overview" />
<div className={s0.root}>
<div>
<TrafficNow />
</div>
<div className={s0.chart}>
<TrafficChart />
</div>
</div>
);
}
</div>
);
}
export default Home;

View file

@ -1,7 +1,7 @@
import React from 'react';
import { Provider } from 'react-redux';
import { HashRouter as Router, Route } from 'react-router-dom';
import { hot } from 'react-hot-loader';
// import { hot } from 'react-hot-loader';
// import createHistory from 'history/createHashHistory';
// import createHistory from 'history/createBrowserHistory';
@ -43,4 +43,9 @@ const Root = () => (
// hot export Root
// https://github.com/gaearon/react-hot-loader/tree/v4.0.1#getting-started
export default hot(module)(Root);
// RHL doesn't compatible with React Hook yet, see:
// https://github.com/gaearon/react-hot-loader/issues/1088
// after it's working, uncommment below line and remove "//" in the babelrc
// export default hot(module)(Root);
export default Root;

View file

@ -1,4 +1,4 @@
import React, { Component } from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import { NavLink } from 'react-router-dom';
@ -12,41 +12,34 @@ import yacd from 's/yacd.svg';
import s from 'c/SideBar.module.scss';
class SideBarRow extends Component {
static propTypes = {
to: PropTypes.string.isRequired,
iconId: PropTypes.string,
labelText: PropTypes.string
};
render() {
const { iconId, labelText, to } = this.props;
return (
<NavLink exact to={to} className={s.row} activeClassName={s.rowActive}>
<Icon id={iconId} width={28} height={28} />
<div className={s.label}>{labelText}</div>
</NavLink>
);
}
function SideBarRow({ iconId, labelText, to }) {
return (
<NavLink exact to={to} className={s.row} activeClassName={s.rowActive}>
<Icon id={iconId} width={28} height={28} />
<div className={s.label}>{labelText}</div>
</NavLink>
);
}
class SideBar extends Component {
render() {
return (
<div className={s.root}>
<div className={s.logo}>
<Icon id={yacd.id} width={80} height={80} />
</div>
SideBarRow.propTypes = {
to: PropTypes.string.isRequired,
iconId: PropTypes.string,
labelText: PropTypes.string
};
<div className={s.rows}>
<SideBarRow to="/" iconId={activity.id} labelText="Overview" />
<SideBarRow to="/proxies" iconId={globe.id} labelText="Proxies" />
<SideBarRow to="/configs" iconId={settings.id} labelText="Config" />
<SideBarRow to="/logs" iconId={file.id} labelText="Logs" />
</div>
export default function SideBar() {
return (
<div className={s.root}>
<div className={s.logo}>
<Icon id={yacd.id} width={80} height={80} />
</div>
);
}
}
export default SideBar;
<div className={s.rows}>
<SideBarRow to="/" iconId={activity.id} labelText="Overview" />
<SideBarRow to="/proxies" iconId={globe.id} labelText="Proxies" />
<SideBarRow to="/configs" iconId={settings.id} labelText="Config" />
<SideBarRow to="/logs" iconId={file.id} labelText="Logs" />
</div>
</div>
);
}

View file

@ -1,45 +1,35 @@
import React, { Component } from 'react';
import React, { useState, useEffect } from 'react';
import prettyBytes from 'm/pretty-bytes';
import { fetchData } from '../api/traffic';
import s0 from 'c/TrafficNow.module.scss';
class TrafficNow extends Component {
state = {
upStr: '0 B/s',
downStr: '0 B/s'
};
componentDidMount() {
this.traffic = fetchData();
this.unsubscribe = this.traffic.subscribe(o => {
this.setState({
upStr: prettyBytes(o.up) + '/s',
downStr: prettyBytes(o.down) + '/s'
});
});
}
componentWillUnmount() {
this.unsubscribe();
}
render() {
const { upStr, downStr } = this.state;
return (
<div className={s0.TrafficNow}>
<div className={s0.up}>
<div>Upload</div>
<div>{upStr}</div>
</div>
<div className={s0.down}>
<div>Download</div>
<div>{downStr}</div>
</div>
export default function TrafficNow() {
const { upStr, downStr } = useSpeed();
return (
<div className={s0.TrafficNow}>
<div className={s0.up}>
<div>Upload</div>
<div>{upStr}</div>
</div>
);
}
<div className={s0.down}>
<div>Download</div>
<div>{downStr}</div>
</div>
</div>
);
}
export default TrafficNow;
function useSpeed() {
const [speed, setSpeed] = useState({ upStr: '0 B/s', downStr: '0 B/s' });
useEffect(() => {
return fetchData().subscribe(o =>
setSpeed({
upStr: prettyBytes(o.up) + '/s',
downStr: prettyBytes(o.down) + '/s'
})
);
});
return speed;
}

View file

@ -1086,11 +1086,6 @@ ansi-colors@^3.0.0:
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.0.5.tgz#cb9dc64993b64fd6945485f797fc3853137d9a7b"
integrity sha512-VVjWpkfaphxUBFarydrQ3n26zX5nIK7hcbT3/ielrvwDDyBBjuh2vuSw1P9zkPq0cfqvdw7lkYHnu+OLSfIBsg==
ansi-escapes@^1.0.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e"
integrity sha1-06ioOzGapneTZisT52HHkRQiMG4=
ansi-escapes@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30"
@ -4670,21 +4665,7 @@ listr-silent-renderer@^1.1.1:
resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e"
integrity sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=
listr-update-renderer@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.4.0.tgz#344d980da2ca2e8b145ba305908f32ae3f4cc8a7"
integrity sha1-NE2YDaLKLosUW6MFkI8yrj9MyKc=
dependencies:
chalk "^1.1.3"
cli-truncate "^0.2.1"
elegant-spinner "^1.0.1"
figures "^1.7.0"
indent-string "^3.0.0"
log-symbols "^1.0.2"
log-update "^1.0.2"
strip-ansi "^3.0.1"
"listr-update-renderer@https://github.com/okonet/listr-update-renderer/tarball/upgrade-log-update":
listr-update-renderer@^0.4.0, "listr-update-renderer@https://github.com/okonet/listr-update-renderer/tarball/upgrade-log-update":
version "0.4.0"
resolved "https://github.com/okonet/listr-update-renderer/tarball/upgrade-log-update#06073fa93166277607a7814f4e1f83960081414c"
dependencies:
@ -4857,14 +4838,6 @@ log-symbols@^2.2.0:
dependencies:
chalk "^2.0.1"
log-update@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/log-update/-/log-update-1.0.2.tgz#19929f64c4093d2d2e7075a1dad8af59c296b8d1"
integrity sha1-GZKfZMQJPS0ucHWh2tivWcKWuNE=
dependencies:
ansi-escapes "^1.0.0"
cli-cursor "^1.0.2"
log-update@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708"
@ -6630,15 +6603,15 @@ rc@^1.2.7:
minimist "^1.2.0"
strip-json-comments "~2.0.1"
react-dom@^16.6.0:
version "16.6.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.6.0.tgz#6375b8391e019a632a89a0988bce85f0cc87a92f"
integrity sha512-Stm2D9dXEUUAQdvpvhvFj/DEXwC2PAL/RwEMhoN4dvvD2ikTlJegEXf97xryg88VIAU22ZAP7n842l+9BTz6+w==
react-dom@^16.7.0-alpha.0:
version "16.7.0-alpha.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.7.0-alpha.0.tgz#8379158d4c76d63c989f325f45dfa5762582584f"
integrity sha512-/XUn1ldxmoV2B7ov0rWT5LMZaaHMlF9GGLkUsmPRxmWTJwRDOuAPXidSaSlmR/VOhDSI1s+v3+KzFqhhDFJxYA==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
prop-types "^15.6.2"
scheduler "^0.10.0"
scheduler "^0.11.0-alpha.0"
react-hot-loader@^4.2.0:
version "4.3.11"
@ -6709,15 +6682,15 @@ react-router@^4.4.0-beta.4:
path-to-regexp "^1.7.0"
warning "^4.0.1"
react@^16.6.0:
version "16.6.0"
resolved "https://registry.yarnpkg.com/react/-/react-16.6.0.tgz#b34761cfaf3e30f5508bc732fb4736730b7da246"
integrity sha512-zJPnx/jKtuOEXCbQ9BKaxDMxR0001/hzxXwYxG8septeyYGfsgAei6NgfbVgOhbY1WOP2o3VPs/E9HaN+9hV3Q==
react@^16.7.0-alpha.0:
version "16.7.0-alpha.0"
resolved "https://registry.yarnpkg.com/react/-/react-16.7.0-alpha.0.tgz#e2ed4abe6f268c9b092a1d1e572953684d1783a9"
integrity sha512-V0za4H01aoAF0SdzahHepvfvzTQ1xxkgMX4z8uKzn+wzZAlVk0IVpleqyxZWluqmdftNedj6fIIZRO/rVYVFvQ==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
prop-types "^15.6.2"
scheduler "^0.10.0"
scheduler "^0.11.0-alpha.0"
read-pkg-up@^1.0.1:
version "1.0.1"
@ -7169,10 +7142,10 @@ sax@^1.2.4, sax@~1.2.4:
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
scheduler@^0.10.0:
version "0.10.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.10.0.tgz#7988de90fe7edccc774ea175a783e69c40c521e1"
integrity sha512-+TSTVTCBAA3h8Anei3haDc1IRwMeDmtI/y/o3iBe3Mjl2vwYF9DtPDt929HyRmV/e7au7CLu8sc4C4W0VOs29w==
scheduler@^0.11.0-alpha.0:
version "0.11.0-alpha.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.11.0-alpha.0.tgz#7b132c726608993471db07866f2d59a52b9e190b"
integrity sha512-0tUDHYSyni/EHkMMBysVXVwfanCWWbLsulnDB1tGrQiWWrVuRVoclWCPHCYC/1iR5Rj34EQhxh3/F36V+F+ZpA==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"