Rails + React + Redux - Pt 8
I'm actually really happy to be tinkering in React and Redux again! I've been spending a lot of time learning Python/Django and some time exploring Docker and Heroku. In this post I'm going to focus in on directory structure within the "/frontend" (React client) directory and some primary files within (index.js, app.js, root_reducer.js, etc).
Let's get started!
Below I'm introducing a web app called workflowy.com that I really enjoy using to plan projects and keep notes. It works really well organized by directories and files. In my first pass at this project I had far fewer files and directories but they grew really fast. I've found that it's better just to set as broad of a base structure first and refactor down once the project is closer to some form of completion.
The top level index.js file is your standard React index file.
import thunk from 'redux-thunk'; | |
import 'semantic-ui-css/semantic.min.css'; | |
import { Route, BrowserRouter } from 'react-router-dom'; | |
import { createStore, applyMiddleware, compose} from 'redux'; | |
import './index.css'; | |
import App from './components/App'; | |
import rootReducer from './reducers/rootReducer'; | |
// I generally comment out the serviceWorker code | |
//import * as serviceWorker from './serviceWorker'; | |
// 13 is required to make use of redux devtools, an aboslute must for me when debugging | |
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; | |
// the store construction could be abstracted out into the reducers directory, but I like it here. | |
const store = createStore( | |
rootReducer, | |
composeEnhancers( | |
applyMiddleware(thunk)) | |
); | |
// lines 23 - 30 are really standard in react/redux development | |
ReactDOM.render( | |
<Provider store={store}> | |
<BrowserRouter> | |
<Route path="/" component={App} /> | |
</BrowserRouter> | |
</Provider>, | |
document.getElementById('root') | |
); | |
// If you want your app to work offline and load faster, you can change | |
// unregister() to register() below. Note this comes with some pitfalls. | |
// Learn more about service workers: https://bit.ly/CRA-PWA | |
//serviceWorker.unregister(); |
The App.js file is really self-explanatory as well. Enjoy the simplicity before we jump into actions and reducers!
import React, { Component } from 'react'; | |
import { connect } from 'react-redux'; | |
import { bindActionCreators } from 'redux' | |
import { Route } from 'react-router-dom'; | |
import NavBar from './common/NavBar' | |
import * as actions from '../actions/index' | |
import QueensContainer from './queens/QueensContainer' | |
import SeasonsContainer from './seasons/SeasonsContainer'; | |
class App extends Component { | |
componentDidMount = () => { | |
this.props.actions.fetchQueens(); | |
this.props.actions.fetchSeasons(); | |
} | |
render() { | |
return ( | |
<div className="App"> | |
<NavBar dragQueens={this.props.dragQueens}/> | |
<Route exact path="/" | |
render={() => (<h3>Welcome to DRAGnet!</h3>)} /> | |
<Route path="/queens" | |
render={routerProps => <QueensContainer {...routerProps} | |
dragQueens={this.props.dragQueens} | |
rpdrSeasons={this.props.rpdrSeasons}/>} /> | |
<Route path="/seasons" | |
render={routerProps => <SeasonsContainer {...routerProps} | |
rpdrSeasons={this.props.rpdrSeasons} /> }/> | |
</div> | |
); | |
} | |
} | |
function mapStateToProps(state) { | |
return { dragQueens: state.queens.drag_queens, | |
rpdrSeasons: state.seasons.rpdr_seasons}; | |
}; | |
const mapDispatchToProps = dispatch => { | |
return { | |
actions: bindActionCreators(actions, dispatch) | |
}; | |
}; | |
export default connect(mapStateToProps, mapDispatchToProps)(App); |
The next post will cover the actions files, where we need to make our fetch calls to retrieve the data from the Rails backend.
Top comments (0)