aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoah Loomans <noahloomans@gmail.com>2018-06-26 22:25:55 +0200
committerNoah Loomans <noahloomans@gmail.com>2018-06-26 22:25:55 +0200
commitdedf8025a547d698d9f2e62f0897493d61ffadd5 (patch)
treebb1736fad1f20294c0ce9b53d6d33c07e7d1dcfe
parent315adeb5e2012b7f7bcfcd1478f9d6dd2cc1092d (diff)
Use mapStateToProps for router simplification
-rw-r--r--src/client/react/components/container/Menu.js47
-rw-r--r--src/client/react/components/container/Results.js30
-rw-r--r--src/client/react/components/container/RoomFinder.js40
-rw-r--r--src/client/react/components/container/Search.js14
-rw-r--r--src/client/react/components/container/WeekSelector.js29
-rw-r--r--src/client/react/components/page/User.js16
-rw-r--r--src/client/react/lib/url.js22
7 files changed, 107 insertions, 91 deletions
diff --git a/src/client/react/components/container/Menu.js b/src/client/react/components/container/Menu.js
index 474444d..85fa785 100644
--- a/src/client/react/components/container/Menu.js
+++ b/src/client/react/components/container/Menu.js
@@ -26,38 +26,32 @@ import { Button, ButtonIcon } from 'rmwc/Button';
import { SimpleMenu, MenuItem } from 'rmwc/Menu';
import { Icon } from 'rmwc/Icon';
import users from '../../users';
-import { setUser, userFromMatch } from '../../lib/url';
+import { makeSetUser, userFromMatch } from '../../lib/url';
import './Menu.scss';
class Menu extends React.Component {
static propTypes = {
- // redux
- dispatch: PropTypes.func.isRequired,
+ setUser: PropTypes.func.isRequired,
+ user: PropTypes.string,
+ showRoomFinder: PropTypes.func.isRequired,
+ }
- // react-router
- match: PropTypes.object.isRequired,
- location: PropTypes.object.isRequired,
- history: PropTypes.object.isRequired,
+ static defaultProps = {
+ user: null,
}
onItemSelected(index) {
switch (index) {
case 'room_finder': {
- const {
- match,
- location,
- history,
- dispatch,
- } = this.props;
- const user = userFromMatch(match);
+ const { setUser, user, showRoomFinder } = this.props;
if (user == null || users.byId[user].type !== 'r') {
// We are not currently viewing a room, correct the situation.
- setUser(users.allRoomIds[0], location, history);
+ setUser(users.allRoomIds[0]);
}
- dispatch({ type: 'ROOM_FINDER/SHOW' });
+ showRoomFinder();
break;
}
default:
@@ -73,7 +67,7 @@ class Menu extends React.Component {
<Button>
<ButtonIcon use="more_vert" />
</Button>
-)}
+ )}
onSelected={(event) => {
// Send the `data-type` of the selected <MenuItem />
this.onItemSelected(event.detail.item.dataset.type);
@@ -81,20 +75,20 @@ class Menu extends React.Component {
>
<MenuItem data-type="add_label">
<Icon use="bookmark_border" />
-Voeg label toe
+ Voeg label toe
</MenuItem>
<MenuItem data-type="make_favorite">
<Icon use="star_border" />
-Maak favoriet
+ Maak favoriet
</MenuItem>
<div className="mdc-list-divider" role="separator" />
<MenuItem data-type="room_finder">
<Icon use="location_searching" />
-Lokaal zoeken
+ Lokaal zoeken
</MenuItem>
<MenuItem data-type="use_legacy_schedule">
<Icon use="launch" />
-Oud rooster gebruiken
+ Oud rooster gebruiken
</MenuItem>
</SimpleMenu>
</div>
@@ -102,4 +96,13 @@ Oud rooster gebruiken
}
}
-export default withRouter(connect()(Menu));
+const mapStateToProps = (state, { match, location, history }) => ({
+ user: userFromMatch(match),
+ setUser: makeSetUser(location, history),
+});
+
+const mapDispatchToProps = dispatch => ({
+ showRoomFinder: () => dispatch({ type: 'ROOM_FINDER/SHOW' }),
+});
+
+export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Menu));
diff --git a/src/client/react/components/container/Results.js b/src/client/react/components/container/Results.js
index 314bbca..c52e43e 100644
--- a/src/client/react/components/container/Results.js
+++ b/src/client/react/components/container/Results.js
@@ -25,7 +25,7 @@ import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import users from '../../users';
-import { setUser, userFromMatch } from '../../lib/url';
+import { makeSetUser, userFromMatch } from '../../lib/url';
import Result from '../presentational/Result';
import './Results.scss';
@@ -37,9 +37,8 @@ class Results extends React.Component {
selectedResult: PropTypes.string,
// react-router
- match: PropTypes.object.isRequired,
- location: PropTypes.object.isRequired,
- history: PropTypes.object.isRequired,
+ user: PropTypes.string,
+ setUser: PropTypes.func.isRequired,
// redux
dispatch: PropTypes.func.isRequired,
@@ -47,6 +46,7 @@ class Results extends React.Component {
static defaultProps = {
selectedResult: null,
+ user: null,
};
render() {
@@ -54,12 +54,10 @@ class Results extends React.Component {
searchText,
results,
selectedResult,
- match,
- location,
- history,
+ user,
+ setUser,
dispatch,
} = this.props;
- const user = userFromMatch(match);
const isExactMatch = (
user != null && searchText === users.byId[user].value
@@ -74,19 +72,19 @@ class Results extends React.Component {
minHeight: isExactMatch ? 0 : results.length * 54,
}}
>
- {!isExactMatch && results.map(userId => (
+ {!isExactMatch && results.map(resultUser => (
<Result
- key={userId}
- userId={userId}
- isSelected={userId === selectedResult}
+ key={resultUser}
+ userId={resultUser}
+ isSelected={resultUser === selectedResult}
onClick={() => {
- if (userId === user) {
+ if (resultUser === user) {
// EDGE CASE: The user is set if the user changes, but it doesn't
// change if the result is already the one we are viewing.
// Therefor, we need to dispatch the SET_USER command manually.
dispatch({ type: 'SEARCH/SET_USER', user });
} else {
- setUser(userId, location, history);
+ setUser(resultUser);
}
}}
/>
@@ -96,7 +94,9 @@ class Results extends React.Component {
}
}
-const mapStateToProps = state => ({
+const mapStateToProps = (state, { match, location, history }) => ({
+ user: userFromMatch(match),
+ setUser: makeSetUser(location, history),
results: state.search.results,
searchText: state.search.text,
selectedResult: state.search.result,
diff --git a/src/client/react/components/container/RoomFinder.js b/src/client/react/components/container/RoomFinder.js
index 0d296a2..f6e7ac6 100644
--- a/src/client/react/components/container/RoomFinder.js
+++ b/src/client/react/components/container/RoomFinder.js
@@ -24,7 +24,7 @@ import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { Button, ButtonIcon } from 'rmwc/Button';
import users from '../../users';
-import { setUser, userFromMatch } from '../../lib/url';
+import { makeSetUser, userFromMatch } from '../../lib/url';
import './RoomFinder.scss';
@@ -32,38 +32,36 @@ class RoomFinder extends React.Component {
static propTypes = {
// redux
isVisible: PropTypes.bool.isRequired,
- dispatch: PropTypes.func.isRequired,
+ onHide: PropTypes.func.isRequired,
// react-router
- match: PropTypes.object.isRequired,
- location: PropTypes.object.isRequired,
- history: PropTypes.object.isRequired,
+ user: PropTypes.string.isRequired,
+ setUser: PropTypes.func.isRequired,
}
componentWillMount() {
- const { isVisible, match, dispatch } = this.props;
- const user = userFromMatch(match);
+ const { isVisible, user, onHide } = this.props;
if (isVisible && users.byId[user].type !== 'r') {
// We are not currently viewing a room, so just hide.
- dispatch({ type: 'ROOM_FINDER/HIDE' });
+ onHide();
}
}
componentWillReceiveProps(nextProps) {
- const { isVisible, match, dispatch } = nextProps;
+ const { isVisible, user, onHide } = nextProps;
- const user = userFromMatch(match);
if (isVisible && users.byId[user].type !== 'r') {
// We are not currently viewing a room, so just hide.
- dispatch({ type: 'ROOM_FINDER/HIDE' });
+ onHide();
}
}
changeRoom(change) {
- const { match, location, history } = this.props;
+ const { user, setUser } = this.props;
const { allRoomIds } = users;
- const currentRoom = userFromMatch(match);
+
+ const currentRoom = user;
const currentRoomIndex = allRoomIds.indexOf(currentRoom);
let nextRoomIndex = currentRoomIndex + change;
if (nextRoomIndex < 0) {
@@ -73,11 +71,11 @@ class RoomFinder extends React.Component {
}
const nextRoom = allRoomIds[nextRoomIndex];
- setUser(nextRoom, location, history);
+ setUser(nextRoom);
}
render() {
- const { isVisible, dispatch } = this.props;
+ const { isVisible, onHide } = this.props;
if (!isVisible) {
return <div />;
}
@@ -93,7 +91,7 @@ class RoomFinder extends React.Component {
<div className="grow" />
<Button
className="closeButton"
- onClick={() => dispatch({ type: 'ROOM_FINDER/HIDE' })}
+ onClick={onHide}
>
<ButtonIcon use="close" />
</Button>
@@ -102,8 +100,14 @@ class RoomFinder extends React.Component {
}
}
-const mapStateToProps = state => ({
+const mapStateToProps = (state, { match, location, history }) => ({
+ user: userFromMatch(match),
+ setUser: makeSetUser(location, history),
isVisible: state.isRoomFinderVisible,
});
-export default withRouter(connect(mapStateToProps)(RoomFinder));
+const mapDispatchToProps = dispatch => ({
+ onHide: () => dispatch({ type: 'ROOM_FINDER/HIDE' }),
+});
+
+export default withRouter(connect(mapStateToProps, mapDispatchToProps)(RoomFinder));
diff --git a/src/client/react/components/container/Search.js b/src/client/react/components/container/Search.js
index 5f00384..65b2933 100644
--- a/src/client/react/components/container/Search.js
+++ b/src/client/react/components/container/Search.js
@@ -26,7 +26,7 @@ import { withRouter } from 'react-router-dom';
import SearchIcon from 'react-icons/lib/md/search';
-import { setUser, userFromMatch } from '../../lib/url';
+import { makeSetUser, userFromMatch } from '../../lib/url';
import users from '../../users';
import Menu from './Menu';
@@ -43,9 +43,7 @@ class Search extends React.Component {
// react-router
match: PropTypes.object.isRequired,
- location: PropTypes.object.isRequired,
- history: PropTypes.object.isRequired,
-
+ setUser: PropTypes.func.isRequired,
// redux
dispatch: PropTypes.func.isRequired,
};
@@ -99,8 +97,7 @@ class Search extends React.Component {
selectedResult,
results,
match,
- location,
- history,
+ setUser,
dispatch,
} = this.props;
@@ -131,7 +128,7 @@ class Search extends React.Component {
// Therefor, we need to dispatch the SET_USER command manually.
dispatch({ type: 'SEARCH/SET_USER', user: urlUser });
} else if (result) {
- setUser(result, location, history);
+ setUser(result);
}
break;
@@ -186,7 +183,8 @@ class Search extends React.Component {
}
}
-const mapStateToProps = state => ({
+const mapStateToProps = (state, { location, history }) => ({
+ setUser: makeSetUser(location, history),
results: state.search.results,
searchText: state.search.text,
selectedResult: state.search.selected,
diff --git a/src/client/react/components/container/WeekSelector.js b/src/client/react/components/container/WeekSelector.js
index 80ad754..19a3947 100644
--- a/src/client/react/components/container/WeekSelector.js
+++ b/src/client/react/components/container/WeekSelector.js
@@ -21,27 +21,27 @@
import React from 'react';
import PropTypes from 'prop-types';
import moment from 'moment';
+import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import ArrowBackIcon from 'react-icons/lib/md/arrow-back';
import ArrowForwardIcon from 'react-icons/lib/md/arrow-forward';
import purifyWeek from '../../lib/purifyWeek';
-import { setWeek, weekFromLocation } from '../../lib/url';
+import { makeSetWeek, weekFromLocation } from '../../lib/url';
import './WeekSelector.scss';
class WeekSelector extends React.Component {
static propTypes = {
// react-router
- location: PropTypes.object.isRequired,
- history: PropTypes.object.isRequired,
+ week: PropTypes.number.isRequired,
+ setWeek: PropTypes.func.isRequired,
};
getWeekText() {
- const { location } = this.props;
+ const { week } = this.props;
- const week = weekFromLocation(location);
const currentWeek = moment().week();
switch (week) {
@@ -57,17 +57,11 @@ class WeekSelector extends React.Component {
}
updateWeek(change) {
- const { location, history } = this.props;
- const week = weekFromLocation(location);
-
+ const { week, setWeek } = this.props;
const newWeek = purifyWeek(week + change);
- const isCurrentWeek = moment().week() === newWeek;
- setWeek(
- isCurrentWeek ? undefined : newWeek,
- location,
- history,
- );
+ const isCurrentWeek = moment().week() === newWeek;
+ setWeek(isCurrentWeek ? undefined : newWeek);
}
render() {
@@ -87,4 +81,9 @@ class WeekSelector extends React.Component {
}
}
-export default withRouter(WeekSelector);
+const mapStateToProps = (state, { location, history }) => ({
+ week: weekFromLocation(location),
+ setWeek: makeSetWeek(location, history),
+});
+
+export default withRouter(connect(mapStateToProps)(WeekSelector));
diff --git a/src/client/react/components/page/User.js b/src/client/react/components/page/User.js
index 4b9af64..af14188 100644
--- a/src/client/react/components/page/User.js
+++ b/src/client/react/components/page/User.js
@@ -20,6 +20,7 @@
import React from 'react';
import PropTypes from 'prop-types';
+import { connect } from 'react-redux';
import { Redirect } from 'react-router-dom';
import { Elevation } from 'rmwc/Elevation';
import Search from '../container/Search';
@@ -33,12 +34,15 @@ import './User.scss';
class UserPage extends React.Component {
static propTypes = {
// react-router
- match: PropTypes.object.isRequired,
+ user: PropTypes.string,
};
+ static defaultProps = {
+ user: null,
+ }
+
render() {
- const { match } = this.props;
- const user = userFromMatch(match);
+ const { user } = this.props;
if (!user) {
// Invalid user, redirect to index.
@@ -66,4 +70,8 @@ class UserPage extends React.Component {
}
}
-export default UserPage;
+const mapStateToProps = (state, { match }) => ({
+ user: userFromMatch(match),
+});
+
+export default connect(mapStateToProps)(UserPage);
diff --git a/src/client/react/lib/url.js b/src/client/react/lib/url.js
index be09acf..c94383c 100644
--- a/src/client/react/lib/url.js
+++ b/src/client/react/lib/url.js
@@ -43,16 +43,20 @@ export function weekFromLocation(location) {
return purifyWeek(parseInt(weekStr, 10));
}
-export function setUser(userId, location, history) {
- const query = location.search;
- history.push(`/${userId}${query}`);
+export function makeSetUser(location, history) {
+ return (userId) => {
+ const query = location.search;
+ history.push(`/${userId}${query}`);
+ };
}
-export function setWeek(week, location, history) {
- const query = queryString.stringify({
- ...queryString.parse(location.search),
- week,
- });
+export function makeSetWeek(location, history) {
+ return (week) => {
+ const query = queryString.stringify({
+ ...queryString.parse(location.search),
+ week,
+ });
- history.push(`${location.pathname}?${query}`);
+ history.push(`${location.pathname}?${query}`);
+ };
}