1
0
mirror of https://github.com/mgerb/mywebsite synced 2026-01-10 09:52:51 +00:00

added redux

This commit is contained in:
2016-08-18 16:10:19 +00:00
parent c572b3806d
commit 2cfda4bb4f
13 changed files with 172 additions and 65 deletions

47
client/js/app.js Normal file
View File

@@ -0,0 +1,47 @@
//react imports
import React from 'react';
import ReactDOM from 'react-dom';
import {Router, Route, IndexRoute} from 'react-router';
//redux imports
import {bindActionCreators} from 'redux';
import {connect, Provider} from 'react-redux';
import store, {history} from './redux/store';
//import actions
import * as actions from './redux/actions';
import Index from './pages/Index';
class Main extends React.Component{
render(){
return(
<div>{React.cloneElement(this.props.children, this.props)}</div>
);
}
}
function mapStateToProps(state){
return {
redux: state.reducer
}
}
function mapDispatchToProps(dispatch){
return{
actions: bindActionCreators(actions, dispatch)
}
}
const App = connect(mapStateToProps, mapDispatchToProps)(Main);
ReactDOM.render((
<Provider store={store}>
<Router history={history}>
<Route path="/" component={App}>
<IndexRoute component={Index}/>
<Route path="/test" component={Index}/>
</Route>
</Router>
</Provider>
),document.getElementById('app'));

View File

@@ -0,0 +1,30 @@
import React from 'react';
import Link from 'react-router';
export default class Preview extends React.Component{
insertPosts(posts){
let elements = [];
for (let i in posts){
elements.push(
<div key={i}>
<h1>{posts[i].title}</h1>
<p>{posts[i].date}</p>
<p>{posts[i].intro}</p>
</div>
);
}
return elements;
}
render(){
const posts = this.props.posts;
return (
<div class="Previews">
{posts.length > 0 ? this.insertPosts(posts): ""}
</div>
);
}
}

View File

@@ -1,20 +0,0 @@
import React from 'react';
export default class Previews extends React.Component{
insertPosts(){
let posts = [];
for (let i = 0; i < 10; i++){
posts.push(<p key={i}>This is a test push {i}</p>);
}
return posts;
}
render(){
return (
<div class="Previews">{this.insertPosts()}</div>
);
}
}

View File

@@ -2,7 +2,7 @@ import React from 'react';
//components
import Header from '../components/Header';
import Previews from '../components/Previews';
import Preview from '../components/Preview';
import Footer from '../components/Footer';
import Sidebar from '../components/Sidebar';
@@ -11,16 +11,20 @@ import '../../assets/css/normalize.css';
import '../../assets/scss/main.scss';
export default class Index extends React.Component{
componentDidMount(){
this.props.actions.fetchPreview();
}
render(){
return(
<div class="Layout">
<Header/>
<div class="Main">
<Previews/>
<Sidebar/>
<div class="Layout">
<Header/>
<div class="Main">
<Preview posts={this.props.redux.preview.posts}/>
<Sidebar />
</div>
<Footer/>
</div>
<Footer/>
</div>
);
}
}

View File

@@ -0,0 +1,23 @@
import * as types from "./constants";
function initPreview(posts){
return{
type: types.INIT_PREVIEW,
posts
}
}
//using redux-thunk we can modify actions before they get called
//in this case we can send the http request here rather in the react component
export function fetchPreview(){
return (dispatch) => {
return fetch('/metadata.json')
.then(response => response.json())
.then(json => {
dispatch(initPreview(json));
})
.catch(error => {
console.log(error);
});
}
}

View File

@@ -0,0 +1,3 @@
//constants
export const INIT_PREVIEW = 'INIT_PREVIEW';
export const FILTER_PREVIEW = 'FILTER_PREVIEW';

View File

@@ -0,0 +1,37 @@
//just using one reducer - use combineReducers from redux to modularize things
import {combineReducers} from 'redux';
import {routerReducer} from 'react-router-redux';
//import typs
import * as types from './constants';
//defaults -
const defaultState = {
preview: {posts: []},
filteredPreview: {posts: []}
};
//default reducer
function reducer(state = defaultState, action){
//every reducer gets called when an action is called - we check for the type to modify our state accordingly
switch (action.type){
case types.INIT_PREVIEW:
return Object.assign({}, state, {
preview: Object.assign({}, state.preview, action.posts)
});
case types.FILTER_PREVIEW:
return Object.assign({}, state, {
filteredPreview: Object.assign({}, state.filteredPreview, action.posts)
})
}
//return present state if no actions get called
return state;
}
const allReducers = combineReducers({
reducer,
routing: routerReducer
});
export default allReducers;

15
client/js/redux/store.js Normal file
View File

@@ -0,0 +1,15 @@
import {applyMiddleware, createStore} from 'redux';
import {syncHistoryWithStore} from 'react-router-redux';
import {browserHistory} from 'react-router';
import thunk from 'redux-thunk';
import reducers from './reducers';
const middleware = applyMiddleware(thunk);
//create the new store with default state as an empty object
const store = createStore(reducers, {}, middleware);
export const history = syncHistoryWithStore(browserHistory, store);
export default store;

View File

@@ -1,22 +0,0 @@
import React from 'react';
import ReactDOM from 'react-dom';
import {browserHistory, Router, Route, IndexRoute} from 'react-router';
import Index from './pages/Index';
class App extends React.Component{
render(){
return(
<div>{React.cloneElement(this.props.children, this.props)}</div>
);
}
}
ReactDOM.render((
<Router history={browserHistory}>
<Route path="/" component={App}>
<IndexRoute component={Index}/>
<Route path="/test" component={Index}/>
</Route>
</Router>
),document.getElementById('app'));