To start off we will be using a small script my team and I created to make your life easier when building full stack applications in CF called cf-create-app. This will install CAP with an approuter, react application, html5 repo service, add Hana and some tweaks so deployment is as straightforward as possible. Simply run
After installation is complete you can simply go into your project folder and run these commands to get the application started. This will start the react app and execute cds watch to get your CAP app running:
Next go into the app folder and we will install some dependencies. First thing we are going to install is connected-react-router and history. Personally I had an issue where installing history version 5.0.0 would cause the redux state not to update properly so if you run into that issue install version 4.10.1 like I did. Run the following commands in the app folder:
After that we need to create a reducer with the specific key router. Personally I like to keep things clean, you may want to create a folder called store inside the src folder with the following files.
Reducers
// PROJECT/app/src/store/reducers.js
import { combineReducers } from 'redux'
;
import { connectRouter } from 'connected-react-router';
export default (history) => combineReducers({
router: connectRouter(history),
... // rest of your reducers
})
If you have worked with redux in the past these reducers file works as usual, just add as many reducers as you may need in your project. If you haven’t worked with redux in the past and enjoy working with react I highly encourage you to start reading about it as it will make your react life incredibly amazing. I particularly enjoy working with Redux Toolkit https://redux-toolkit.js.org/
Moving on, let’s create the store!
Create middleware
// PROJECT/app/src/store/configureStore.js
import { createHashHistory } from 'history';
import { applyMiddleware, compose, createStore } from 'redux';
import { routerMiddleware } from 'connected-react-router'
;
import createRootReducer from './reducers'
;
export const history = createHashHistory({
hashType: 'slash',
getUserConfirmation: (message, callback) => callback(window.confirm(message))
});
export default function configureStore(preloadedState) {
const store = createStore(
createRootReducer(history), // root reducer with router state
preloadedState,
compose(
applyMiddleware(
routerMiddleware(history), // for dispatching history actions
// ... other middlewares ...
),
),
)
return store
}
To make all of this configuration work we will add the configured store to our index.js in our src folder like the following. Take also a look at the route pointing to the wildcard '*'. We are using this to redirect to our home page to avoid broken routes.
Index.js
// PROJECT/app/src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import * as serviceWorker from './serviceWorker';
import { Provider } from 'react-redux';
import { Route, Switch } from 'react-router'; // react-router v4/v5
import { ConnectedRouter } from 'connected-react-router';
import configureStore, { history } from './store/store';
import { Redirect } from 'react-router-dom';
import DefaultComponent from './DefaultComponent';
const store = configureStore(/* provide initial state if any */);
ReactDOM.render(
<Provider store={store}>
{/* place ConnectedRouter under Provider */}
<ConnectedRouter history={history}>
<>
{/* your usual react-router v4/v5 routing */}
<Switch>
<Route
exact
path='/index.html'
render={() => (
<DefaultComponent name='Match' redirect='/miss/index.html' />
)}
/>
<Route
path='/miss/index.html'
render={() => (
<DefaultComponent name='Miss' redirect='/index.html' />
)}
/>
<Route path='*' render={() => <Redirect to='/index.html' />} />
</Switch>
</>
</ConnectedRouter>
</Provider>,
document.getElementById('root')
);
serviceWorker.unregister();
Furthermore, you will want to see it in action! So I put together a small component that will help you understand how to do the routing with this library.
DefaultComponent.js
// PROJECT/app/src/DefaultComponent.js
import React from 'react';
import { useDispatch } from 'react-redux';
import { push } from 'connected-react-router';
function DefaultComponent(props) {
const dispatch = useDispatch();
function handleRouting(r) {
dispatch(push(r));
}
return (
<div>
<button onClick={() => handleRouting(props.redirect)}>
{props.name}
</button>
</div>
);
}
export default DefaultComponent;
We have learnt how to implement basic hash routing, how to ‘push’ to a different route and how to redirect. You can try it locally by clicking the buttons ‘Match’ and ‘Miss’ of you react app - see how the route changes. Let’s move to the cloud!
With the library cf-create-app all modules are added and configured in your mta.yaml so you don’t have to do anything manually, unless you want to add your own services or tweak them by yourself. It has been configured so you only have to build and deploy ?
Run the following commands in your project’s folder:
Today we have learnt how to quickly create an application using CAP + approuter + react + html5 repo service. The react application will be deployed in the HTML5 Repo service and consumed by the approuter. In order to navigate through our app we’ve implemented hash routing which prevents our routes from breaking.
If you like cf-create-app please follow and support
https://github.com/turutupa/cf-create-app
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
20 | |
11 | |
8 | |
8 | |
8 | |
7 | |
7 | |
6 | |
6 | |
6 |