mirror of
https://github.com/mgerb/mywebsite
synced 2026-01-10 09:52:51 +00:00
added redux
This commit is contained in:
47
client/js/app.js
Normal file
47
client/js/app.js
Normal 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'));
|
||||
30
client/js/components/Preview.js
Normal file
30
client/js/components/Preview.js
Normal 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>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
23
client/js/redux/actions.js
Normal file
23
client/js/redux/actions.js
Normal 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);
|
||||
});
|
||||
}
|
||||
}
|
||||
3
client/js/redux/constants.js
Normal file
3
client/js/redux/constants.js
Normal file
@@ -0,0 +1,3 @@
|
||||
//constants
|
||||
export const INIT_PREVIEW = 'INIT_PREVIEW';
|
||||
export const FILTER_PREVIEW = 'FILTER_PREVIEW';
|
||||
37
client/js/redux/reducers.js
Normal file
37
client/js/redux/reducers.js
Normal 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
15
client/js/redux/store.js
Normal 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;
|
||||
@@ -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'));
|
||||
Reference in New Issue
Block a user