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" "@babel/plugin-proposal-do-expressions"
], ],
"env": { "env": {
"development": { "//development": {
"plugins": [ "plugins": [
"react-hot-loader/babel" "react-hot-loader/babel"
] ]

View file

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

View file

@ -8,10 +8,12 @@ import Root from './components/Root';
Modal.setAppElement('#app'); Modal.setAppElement('#app');
// use async React // use async React
const root = ReactDOM.unstable_createRoot(document.getElementById('app')); const root = ReactDOM.createRoot(document.getElementById('app'));
root.render(<Root />); root.render(<Root />);
// const render = (Component, props = {}) => { // const render = (Component, props = {}) => {
// ReactDOM.render(<Component {...props} />, document.getElementById('app')); // ReactDOM.render(<Component {...props} />, document.getElementById('app'));
// }; // };
// render(Root, props); // 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 React from 'react';
// import PropTypes from 'prop-types';
import ContentHeader from 'c/ContentHeader'; import ContentHeader from 'c/ContentHeader';
import TrafficChart from 'c/TrafficChart'; import TrafficChart from 'c/TrafficChart';
import TrafficNow from 'c/TrafficNow'; import TrafficNow from 'c/TrafficNow';
import s0 from 'c/Home.module.scss'; import s0 from 'c/Home.module.scss';
class Home extends Component { export default function Home() {
// static propTypes = { return (
// match: PropTypes.object <div>
// }; <ContentHeader title="Overview" />
<div className={s0.root}>
render() { <div>
// const { match } = this.props; <TrafficNow />
return ( </div>
<div> <div className={s0.chart}>
<ContentHeader title="Overview" /> <TrafficChart />
<div className={s0.root}>
<div>
<TrafficNow />
</div>
<div className={s0.chart}>
<TrafficChart />
</div>
</div> </div>
</div> </div>
); </div>
} );
} }
export default Home;

View file

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import { HashRouter as Router, Route } from 'react-router-dom'; 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/createHashHistory';
// import createHistory from 'history/createBrowserHistory'; // import createHistory from 'history/createBrowserHistory';
@ -43,4 +43,9 @@ const Root = () => (
// hot export Root // hot export Root
// https://github.com/gaearon/react-hot-loader/tree/v4.0.1#getting-started // 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 PropTypes from 'prop-types';
import { NavLink } from 'react-router-dom'; import { NavLink } from 'react-router-dom';
@ -12,41 +12,34 @@ import yacd from 's/yacd.svg';
import s from 'c/SideBar.module.scss'; import s from 'c/SideBar.module.scss';
class SideBarRow extends Component { function SideBarRow({ iconId, labelText, to }) {
static propTypes = { return (
to: PropTypes.string.isRequired, <NavLink exact to={to} className={s.row} activeClassName={s.rowActive}>
iconId: PropTypes.string, <Icon id={iconId} width={28} height={28} />
labelText: PropTypes.string <div className={s.label}>{labelText}</div>
}; </NavLink>
);
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>
);
}
} }
class SideBar extends Component { SideBarRow.propTypes = {
render() { to: PropTypes.string.isRequired,
return ( iconId: PropTypes.string,
<div className={s.root}> labelText: PropTypes.string
<div className={s.logo}> };
<Icon id={yacd.id} width={80} height={80} />
</div>
<div className={s.rows}> export default function SideBar() {
<SideBarRow to="/" iconId={activity.id} labelText="Overview" /> return (
<SideBarRow to="/proxies" iconId={globe.id} labelText="Proxies" /> <div className={s.root}>
<SideBarRow to="/configs" iconId={settings.id} labelText="Config" /> <div className={s.logo}>
<SideBarRow to="/logs" iconId={file.id} labelText="Logs" /> <Icon id={yacd.id} width={80} height={80} />
</div>
</div> </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 prettyBytes from 'm/pretty-bytes';
import { fetchData } from '../api/traffic'; import { fetchData } from '../api/traffic';
import s0 from 'c/TrafficNow.module.scss'; import s0 from 'c/TrafficNow.module.scss';
class TrafficNow extends Component { export default function TrafficNow() {
state = { const { upStr, downStr } = useSpeed();
upStr: '0 B/s', return (
downStr: '0 B/s' <div className={s0.TrafficNow}>
}; <div className={s0.up}>
<div>Upload</div>
componentDidMount() { <div>{upStr}</div>
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>
</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" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.0.5.tgz#cb9dc64993b64fd6945485f797fc3853137d9a7b"
integrity sha512-VVjWpkfaphxUBFarydrQ3n26zX5nIK7hcbT3/ielrvwDDyBBjuh2vuSw1P9zkPq0cfqvdw7lkYHnu+OLSfIBsg== 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: ansi-escapes@^3.0.0:
version "3.1.0" version "3.1.0"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" 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" resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e"
integrity sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4= integrity sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=
listr-update-renderer@^0.4.0: 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://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":
version "0.4.0" version "0.4.0"
resolved "https://github.com/okonet/listr-update-renderer/tarball/upgrade-log-update#06073fa93166277607a7814f4e1f83960081414c" resolved "https://github.com/okonet/listr-update-renderer/tarball/upgrade-log-update#06073fa93166277607a7814f4e1f83960081414c"
dependencies: dependencies:
@ -4857,14 +4838,6 @@ log-symbols@^2.2.0:
dependencies: dependencies:
chalk "^2.0.1" 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: log-update@^2.3.0:
version "2.3.0" version "2.3.0"
resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708" 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" minimist "^1.2.0"
strip-json-comments "~2.0.1" strip-json-comments "~2.0.1"
react-dom@^16.6.0: react-dom@^16.7.0-alpha.0:
version "16.6.0" version "16.7.0-alpha.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.6.0.tgz#6375b8391e019a632a89a0988bce85f0cc87a92f" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.7.0-alpha.0.tgz#8379158d4c76d63c989f325f45dfa5762582584f"
integrity sha512-Stm2D9dXEUUAQdvpvhvFj/DEXwC2PAL/RwEMhoN4dvvD2ikTlJegEXf97xryg88VIAU22ZAP7n842l+9BTz6+w== integrity sha512-/XUn1ldxmoV2B7ov0rWT5LMZaaHMlF9GGLkUsmPRxmWTJwRDOuAPXidSaSlmR/VOhDSI1s+v3+KzFqhhDFJxYA==
dependencies: dependencies:
loose-envify "^1.1.0" loose-envify "^1.1.0"
object-assign "^4.1.1" object-assign "^4.1.1"
prop-types "^15.6.2" prop-types "^15.6.2"
scheduler "^0.10.0" scheduler "^0.11.0-alpha.0"
react-hot-loader@^4.2.0: react-hot-loader@^4.2.0:
version "4.3.11" version "4.3.11"
@ -6709,15 +6682,15 @@ react-router@^4.4.0-beta.4:
path-to-regexp "^1.7.0" path-to-regexp "^1.7.0"
warning "^4.0.1" warning "^4.0.1"
react@^16.6.0: react@^16.7.0-alpha.0:
version "16.6.0" version "16.7.0-alpha.0"
resolved "https://registry.yarnpkg.com/react/-/react-16.6.0.tgz#b34761cfaf3e30f5508bc732fb4736730b7da246" resolved "https://registry.yarnpkg.com/react/-/react-16.7.0-alpha.0.tgz#e2ed4abe6f268c9b092a1d1e572953684d1783a9"
integrity sha512-zJPnx/jKtuOEXCbQ9BKaxDMxR0001/hzxXwYxG8septeyYGfsgAei6NgfbVgOhbY1WOP2o3VPs/E9HaN+9hV3Q== integrity sha512-V0za4H01aoAF0SdzahHepvfvzTQ1xxkgMX4z8uKzn+wzZAlVk0IVpleqyxZWluqmdftNedj6fIIZRO/rVYVFvQ==
dependencies: dependencies:
loose-envify "^1.1.0" loose-envify "^1.1.0"
object-assign "^4.1.1" object-assign "^4.1.1"
prop-types "^15.6.2" prop-types "^15.6.2"
scheduler "^0.10.0" scheduler "^0.11.0-alpha.0"
read-pkg-up@^1.0.1: read-pkg-up@^1.0.1:
version "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" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
scheduler@^0.10.0: scheduler@^0.11.0-alpha.0:
version "0.10.0" version "0.11.0-alpha.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.10.0.tgz#7988de90fe7edccc774ea175a783e69c40c521e1" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.11.0-alpha.0.tgz#7b132c726608993471db07866f2d59a52b9e190b"
integrity sha512-+TSTVTCBAA3h8Anei3haDc1IRwMeDmtI/y/o3iBe3Mjl2vwYF9DtPDt929HyRmV/e7au7CLu8sc4C4W0VOs29w== integrity sha512-0tUDHYSyni/EHkMMBysVXVwfanCWWbLsulnDB1tGrQiWWrVuRVoclWCPHCYC/1iR5Rj34EQhxh3/F36V+F+ZpA==
dependencies: dependencies:
loose-envify "^1.1.0" loose-envify "^1.1.0"
object-assign "^4.1.1" object-assign "^4.1.1"