Skip to content

Commit

Permalink
Merge pull request #51 from thesbros/master
Browse files Browse the repository at this point in the history
Add TypeScript typings
  • Loading branch information
supasate authored Apr 28, 2017
2 parents 585c116 + 9a9ee9f commit e2836ee
Show file tree
Hide file tree
Showing 21 changed files with 3,101 additions and 0 deletions.
17 changes: 17 additions & 0 deletions examples/typescript/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Connected React Router TypeScript Example

This is the same as the `basic` example, but using TypeScript.

## Install
```bash
yarn
```

## Run
```bash
npm run dev
```

You can try changing counter value and editing some components. Components will be updated while preserving counter state.

In Hello link, you will see that the HelloChild component can access router state (URL path) without passing as props via its parent.
11 changes: 11 additions & 0 deletions examples/typescript/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Minimal Hot Reload</title>
</head>
<body>
<div id="react-root" />
<script src="/dist/bundle.js"></script>
</body>
</html>
37 changes: 37 additions & 0 deletions examples/typescript/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"name": "connected-react-router-example-typescript",
"version": "1.0.0",
"description": "A basic example for Connected React Router with TypeScript",
"main": "src/index.ts",
"scripts": {
"dev": "webpack-dev-server",
"build": "webpack"
},
"author": "Supasate Choochaisri",
"license": "MIT",
"devDependencies": {
"@types/history": "^4.5.0",
"@types/react": "^15.0.23",
"@types/react-dom": "^15.5.0",
"@types/react-hot-loader": "^3.0.1",
"@types/react-redux": "^4.4.40",
"@types/react-router": "^4.0.4",
"@types/react-router-dom": "^4.0.4",
"@types/webpack-env": "^1.13.0",
"react-hot-loader": "^3.0.0-beta",
"ts-loader": "^2.0.3",
"typescript": "^2.3.1",
"webpack": "^2.4.1",
"webpack-dev-server": "^2.4.5"
},
"dependencies": {
"connected-react-router": "^4.1.0",
"history": "^4.6.1",
"react": "^15.5.4",
"react-dom": "^15.5.4",
"react-redux": "^5.0.4",
"react-router": "^4.1.1",
"react-router-dom": "^4.1.1",
"redux": "^3.6.0"
}
}
18 changes: 18 additions & 0 deletions examples/typescript/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react'
import {History} from 'history'
import { ConnectedRouter } from 'connected-react-router'
import routes from './routes'

interface AppProps {
history: History;
}

const App = ({ history }: AppProps) => {
return (
<ConnectedRouter history={history}>
{ routes }
</ConnectedRouter>
)
}

export default App
7 changes: 7 additions & 0 deletions examples/typescript/src/actions/counter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const increment = () => ({
type: 'INCREMENT',
})

export const decrement = () => ({
type: 'DECREMENT',
})
34 changes: 34 additions & 0 deletions examples/typescript/src/components/Counter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react'
import { Dispatch } from 'redux'
import { connect } from 'react-redux'
import { RouteComponentProps } from 'react-router'
import { increment, decrement } from '../actions/counter'
import { State } from '../reducers'

const Counter = (props: RouteComponentProps<any> & StateProps & DispatchProps) => (
<div>
Counter: {props.count}
<button onClick={props.increment}>+</button>
<button onClick={props.decrement}>-</button>
</div>
)

interface StateProps {
count: number
}

interface DispatchProps {
increment: () => void
decrement: () => void
}

const mapStateToProps = (state: State) => ({
count: state.count,
})

const mapDispatchToProps = (dispatch: Dispatch<State>) => ({
increment: () => dispatch(increment()),
decrement: () => dispatch(decrement()),
})

export default connect<StateProps, DispatchProps, RouteComponentProps<any>>(mapStateToProps, mapDispatchToProps)(Counter)
11 changes: 11 additions & 0 deletions examples/typescript/src/components/Hello.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react'
import HelloChild from './HelloChild'

const Hello = () => (
<div>
<div>Hello</div>
<HelloChild />
</div>
)

export default Hello
37 changes: 37 additions & 0 deletions examples/typescript/src/components/HelloChild.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react'
import { connect } from 'react-redux'
import { Link } from 'react-router-dom'
import { State } from '../reducers'

interface HelloChildProps {
pathname: string
search: string
hash: string
}

const HelloChild = ({ pathname, search, hash }: HelloChildProps) => (
<div>
Hello-Child
<ul>
<li><Link to="/hello?color=Blue&size=40">with query string</Link></li>
<li><Link to="/hello#lovelove">with hash</Link></li>
</ul>
<div>
pathname: {pathname}
</div>
<div>
search: {search}
</div>
<div>
hash: {hash}
</div>
</div>
)

const mapStateToProps = (state: State) => ({
pathname: state.router.location.pathname,
search: state.router.location.search,
hash: state.router.location.hash,
})

export default connect(mapStateToProps)(HelloChild)
9 changes: 9 additions & 0 deletions examples/typescript/src/components/Home.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from 'react'

const Home = () => (
<div>
Home
</div>
)

export default Home
10 changes: 10 additions & 0 deletions examples/typescript/src/components/NavBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react'
import { Link } from 'react-router-dom'

const NavBar = () => (
<div>
<div><Link to="/">Home</Link> <Link to="/hello">Hello</Link> <Link to="/counter">Counter</Link></div>
</div>
)

export default NavBar
9 changes: 9 additions & 0 deletions examples/typescript/src/components/NoMatch.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from 'react'

const NoMatch = () => (
<div>
No Match
</div>
)

export default NoMatch
47 changes: 47 additions & 0 deletions examples/typescript/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { AppContainer } from 'react-hot-loader'
import { applyMiddleware, compose, createStore } from 'redux'
import { createBrowserHistory } from 'history'
import { routerMiddleware, connectRouter } from 'connected-react-router'
import { Provider } from 'react-redux'
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
import rootReducer from './reducers'

const history = createBrowserHistory()

const composeEnhancer: typeof compose = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
const store = createStore(
connectRouter(history)(rootReducer),
composeEnhancer(
applyMiddleware(
routerMiddleware(history),
),
),
)

const render = () => {
ReactDOM.render(
<AppContainer>
<Provider store={store}>
<App history={history} />
</Provider>
</AppContainer>,
document.getElementById('react-root')
)
}

render()

// Hot reloading
if (module.hot) {
// Reload components
module.hot.accept('./App', () => {
render()
})

// Reload reducers
module.hot.accept('./reducers', () => {
store.replaceReducer(connectRouter(history)(rootReducer))
})
}
14 changes: 14 additions & 0 deletions examples/typescript/src/reducers/counter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Action } from "redux";

const counterReducer = (state = 0, action: Action) => {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}

export default counterReducer
19 changes: 19 additions & 0 deletions examples/typescript/src/reducers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { combineReducers } from 'redux'
import counterReducer from './counter'

const rootReducer = combineReducers({
count: counterReducer,
})

export interface State {
count: number
router: {
location: {
pathname: string
search: string
hash: string
}
}
}

export default rootReducer
21 changes: 21 additions & 0 deletions examples/typescript/src/routes/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react'
import { Route, Switch } from 'react-router'
import Home from '../components/Home'
import Hello from '../components/Hello'
import Counter from '../components/Counter'
import NoMatch from '../components/NoMatch'
import NavBar from '../components/NavBar'

const routes = (
<div>
<NavBar />
<Switch>
<Route exact path="/" component={Home} />
<Route path="/hello" component={Hello} />
<Route path="/counter" component={Counter} />
<Route component={NoMatch} />
</Switch>
</div>
)

export default routes
31 changes: 31 additions & 0 deletions examples/typescript/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"compilerOptions": {
"module": "es2015",
"moduleResolution": "node",
"target": "es5",


"jsx": "react",
"lib": [
"dom",
"es2017"
],

"alwaysStrict": true,
"sourceMap": true,

"forceConsistentCasingInFileNames": true,
"noImplicitAny": true,
"noFallthroughCasesInSwitch": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"strictNullChecks": true,

"allowSyntheticDefaultImports": true
},

"exclude": [
"node_modules",
"dist"
]
}
33 changes: 33 additions & 0 deletions examples/typescript/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const path = require('path')
const webpack = require('webpack')

module.exports = {
devtool: 'eval-source-map',
entry: [
'react-hot-loader/patch',
path.resolve('src/index.tsx'),
],
resolve: {
extensions: ['.js', '.ts', '.tsx'],
},
devServer: {
historyApiFallback: true,
hot: true,
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/dist/',
},
module: {
rules: [
{
test: /\.tsx?/,
loader: 'ts-loader'
}
],
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
],
}
Loading

0 comments on commit e2836ee

Please sign in to comment.