I am developing a course planning application to respond, and I use it as an opportunity to study abbreviation. There is a browse menu (implemented as a component of the "Overview"), which I am currently developing, and it displays a list of schools at the university at boot time. When a user clicks on one of the schools, he displays a list of topics in that school. However, I would like schools to appear as a grid (two columns), and I would like subjects to be displayed as a list (single column). They may also presumably require the various components to be loaded into the Browse component.
How should I do it? I currently have a Browse component and a BrowseReduxContainer component. The BrowseReduxContainer component uses connect (), mapStateToProps, and mapDispatchToProps for a reduction reaction to populate Browse details. This works fine when I just show schools, but I'm not sure how to change the Browse layout depending on the state. Should I provide connect () various components depending on state? Or should I implement the logic in the Browse component to check support and display the grid / list accordingly? Or something else?
actions.js
export function showSubjects(schoolId) { return { type: 'SHOW_SUBJECTS', schoolId }; }
browse.js
const initialState = { currentView: 'schools', schools: [{id: 'AAAA', name: 'aaaa'}, {id: 'BBBB', name: 'bbbb'}], subjects: [{id: 'CCC', name: 'ccc'}, {id: 'DDD', name: 'ddd'}] }; function browse(state = initialState, action) { switch (action.type) { case 'SHOW_SUBJECTS': return { ...state, currentView: 'subjects' }; default: return state; } } export default browse;
BrowseReduxContainer.jsx
import { connect } from 'react-redux'; import { showSubjects } from '../actions/actions'; import Browse from '../components/Browse.jsx'; function propsFilter(state) { switch (state.currentView) { case 'schools': return state.schools; case 'subjects': return state.subjects; default: throw new Error(`No such view: ${state.currentView}`); } } const mapStateToProps = (state) => ({ schools: propsFilter(state) }); const mapDispatchToProps = (dispatch) => ({ showSubjects: (schoolId) => { dispatch(showSubjects(schoolId)); } }); const BrowseReduxContainer = connect(mapStateToProps, mapDispatchToProps)(Browse); export default BrowseReduxContainer;
Browse.jsx
import React from 'react'; import RaisedButton from 'material-ui/RaisedButton'; const Browse = (props) => ( <div> {props.schools.map((school) => ( <RaisedButton key={school.id} label={school.name} onClick={props.showSubjects(school.id)} /> ))} </div> ); export default Browse;
Other relevant files, if necessary, can be viewed here: https://github.com/Joonpark13/serif.nu/tree/feature/browse
UPDATE: My best guess at this point was to have various view components with their own corresponding attributes, possibly called BrowseA and BrowseB, and put together the appropriate one according to the state. I want to include this logic in mapDispatchToProps in BrowseReduxContainer, but then I realized that the mapDispatchToProps function does not take state as a parameter. I would love any suggestions!