Skip to content

Instantly share code, notes, and snippets.

@dais0n
Created February 24, 2017 12:02
Show Gist options
  • Save dais0n/ec36101b87669e2fcf2e8ada341ed29d to your computer and use it in GitHub Desktop.
Save dais0n/ec36101b87669e2fcf2e8ada341ed29d to your computer and use it in GitHub Desktop.
react and redux and rechats sample
export const REQUEST_SENCERS = 'REQUEST_SENCERS'
export const RECEIVE_SENCERS = 'RECEIVE_SENCERS'
export const REQUEST_MOTIONS = 'REQUEST_MOTIONS'
export const RECEIVE_MOTIONS = 'RECEIVE_MOTIONS'
export const requestSencers = ({
type: REQUEST_SENCERS,
})
export const requestMotions = ({
type: REQUEST_MOTIONS,
})
export const receiveSencers = (json) => ({
type: RECEIVE_SENCERS,
thermohygros: json,
receivedAt: Date.now()
})
export const receiveMotions = (json) => ({
type: RECEIVE_MOTIONS,
motions: json,
receivedAt: Date.now()
})
function fetchSencers() {
return dispatch => {
dispatch(requestSencers)
return fetch(`http://localhost:1323/api/v1/temperatures`)
.then(response => response.json())
.then(json => dispatch(receiveSencers(json)))
}
}
function fetchMotions() {
return dispatch => {
dispatch(requestMotions)
return fetch(`http://localhost:1323/api/v1/motions`)
.then(response => response.json())
.then(json => dispatch(receiveMotions(json)))
}
}
function shouldFetchSencers(state) {
const posts = state.Sencers.thermohygros;
if (posts.length === 0) {
return true;
} else if (state.isFetching) {
return false;
} else {
return state.didInvalidate;
}
}
export function fetchSencersIfNeeded() {
return (dispatch, getState) => {
if (shouldFetchSencers(getState())) {
return dispatch(fetchSencers() , dispatch(fetchMotions()))
}
}
}
import React, { Component, PropTypes } from 'react'
import { connect } from 'react-redux'
import { fetchSencersIfNeeded } from '../actions'
import ThermoHygros from '../components/ThermoHygros'
import getMuiTheme from 'material-ui/styles/getMuiTheme'
import AppBarExampleIcon from '../components/AppBarExampleIcon'
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
import darkBaseTheme from 'material-ui/styles/baseThemes/darkBaseTheme'
import injectTapEventPlugin from 'react-tap-event-plugin'
import Motions from '../components/Motions'
injectTapEventPlugin();
class App extends Component {
static propTypes = {
thermohygros: PropTypes.array.isRequired,
motions: PropTypes.array.isRequired,
isFetching: PropTypes.bool.isRequired,
lastUpdated: PropTypes.number,
dispatch: PropTypes.func.isRequired
}
componentDidMount() {
const { dispatch } = this.props
dispatch(fetchSencersIfNeeded())
}
render() {
const { thermohygros, motions, isFetching, lastUpdated } = this.props
const isThermoEmpty = thermohygros.length === 0
const isMotionEmpty = motions.length === 0
return (
<MuiThemeProvider muiTheme={getMuiTheme(darkBaseTheme)}>
<div>
<AppBarExampleIcon />
<p>
{lastUpdated &&
<span>
Last updated at {new Date(lastUpdated).toLocaleTimeString()}.
{' '}
</span>
}
</p>
{isThermoEmpty
? (isFetching ? <h2>Loading...</h2> : <h2>Empty.</h2>)
: <div style={{ opacity: isFetching ? 0.5 : 1 }}>
<ThermoHygros thermohygros={thermohygros} />
</div>
}
{isMotionEmpty
? (isFetching ? <h2>Loading...</h2> : <h2>Empty.</h2>)
: <div style={{ opacity: isFetching ? 0.5 : 1 }}>
<Motions motions={motions} />
</div>
}
</div>
</MuiThemeProvider>
)
}
}
const mapStateToProps = state => {
const { Sencers } = state
const {
isFetching,
lastUpdated,
thermohygros: thermohygros,
motions: motions
} = Sencers || {
isFetching: true,
thermohygros: [],
motions: []
}
return {
thermohygros,
motions,
isFetching,
lastUpdated
}
}
export default connect(mapStateToProps)(App)
import React from 'react';
import AppBar from 'material-ui/AppBar';
/**
* A simple example of `AppBar` with an icon on the right.
* By default, the left icon is a navigation-menu.
*/
const AppBarExampleIcon = () => (
<AppBar
title="LabMonitor"
iconClassNameRight="muidocs-icon-navigation-expand-more"
/>
);
export default AppBarExampleIcon;
import React from 'react'
import { render } from 'react-dom'
import { createStore, applyMiddleware } from 'redux'
import { Provider } from 'react-redux'
import thunk from 'redux-thunk'
import createLogger from 'redux-logger'
import reducer from './reducers'
import App from './containers/App'
const middleware = [ thunk ]
if (process.env.NODE_ENV !== 'production') {
middleware.push(createLogger())
}
const store = createStore(
reducer,
applyMiddleware(...middleware)
)
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
import {BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend} from 'recharts';
import React, { PropTypes } from 'react'
const Motions = ({motions}) => (
<BarChart width={600} height={300} data={motions}
margin={{top: 5, right: 30, left: 20, bottom: 5}}>
<XAxis dataKey="created_at"/>
<YAxis/>
<CartesianGrid strokeDasharray="3 3"/>
<Tooltip/>
<Legend />
<Bar dataKey="count" fill="#8884d8" />
</BarChart>
)
Motions.PropTypes = {
motions: PropTypes.array.isRequired
}
export default Motions
import { combineReducers } from 'redux'
import { REQUEST_SENCERS, RECEIVE_SENCERS, REQUEST_MOTIONS, RECEIVE_MOTIONS } from '../actions'
const Sencers = (state = {
isFetching: false,
didInvalidate: false,
thermohygros: [],
motions: []
}, action) => {
switch (action.type) {
case REQUEST_SENCERS:
return {
...state,
isFetching: true,
didInvalidate: false
}
case REQUEST_MOTIONS:
return {
...state,
isFetching: true,
didInvalidate: false
}
case RECEIVE_SENCERS:
return {
...state,
isFetching: false,
didInvalidate: false,
thermohygros: action.thermohygros,
lastUpdated: action.receivedAt
}
case RECEIVE_MOTIONS:
return {
...state,
isFetching: false,
didInvalidate: false,
motions: action.motions,
lastUpdated: action.receivedAt
}
default:
return state
}
}
const rootReducer = combineReducers({
Sencers
})
export default rootReducer
import {LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend} from 'recharts';
import React, { PropTypes } from 'react'
const Thermohygros = ({thermohygros}) => (
<LineChart width={600} height={300} data={thermohygros}
margin={{top: 5, right: 30, left: 20, bottom: 5}}>
<XAxis dataKey="created_at"/>
<YAxis/>
<CartesianGrid strokeDasharray="3 3"/>
<Tooltip/>
<Legend />
<Line type="monotone" dataKey="temperature" stroke="#8884d8" activeDot={{r: 8}}/>
<Line type="monotone" dataKey="humidity" stroke="#82ca9d" />
</LineChart>
)
Thermohygros.PropTypes = {
thermohygros: PropTypes.array.isRequired
}
export default Thermohygros
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment