React @ Namics
2017 / 2018





React @ Namics
2017 / 2018

Projects
Projects
Sunrise.ch
Pathe.ch
Migros Impuls Coach
& many other smaller React Projects

Homepage CMS only → SEO

React Widgets

Homepage React & CMS

One React App
Backend
Backend
Bootstrap Apps
Backend Data
i18n
// index.html
<div class="js-react" data-appName="quickBuyWidget" data-productId="64031">
// bootstrap.js
const $apps = $("body").find(".js-react");
$apps.each(function(index, app) {
let htmlNode = app;
const $app = $(app);
const pageData = $app.data();
const appName = $app.data("appName");
const $mountNode = $app.find(".js-react-mount");
$script(`/${appName}.js`, function() {
$(document).trigger("bootstrap-react-app", {
htmlNode, appName, pageData, store, history
});
});
});
Bootstrap Apps 1/2
Bootstrap Apps 2/2
// quickbuyApp.js
$(document).on("bootstrap-react-app", function(event, data) {
if (data.appName !== "quickBuyWidget") return this;
ReactDOM.render(
<RootRedux store={data.store}>
<QuickBuyWidget
productId={data.pageData.productId}
/>
</RootRedux>,
data.htmlNode
);
});
Backend Data
// appConfig.js
window.ReactApp = window.ReactApp || {};
ReactApp.Env = ReactApp.Env || {};
ReactApp.Env.urlMagnolia = "https://pathe-ch.namics-test.com";
ReactApp.Env.urlSolr = "https://pathe-ch.namics-test.com/solr";
ReactApp.Sites = {
PLA: {
label: "Plaza",
wheelChairAreaCode: "0000000005",
preferredComplexID: "1011"
},
KUC: {
label: "Küchlin",
wheelChairAreaCode: "0000000006",
preferredComplexID: "1010"
}
}
i18n
// appConfig.js
window.ReactApp = window.ReactApp || {};
ReactApp.I18n = ReactApp.I18n || {};
ReactApp.I18n = {
'react.impulsCoach.molecules.Record.title': "Your new record is {recordValue}kg"
}
// Record.jsx
<Link
href={routes.dashboard.newMeasurement.href}
title={i18n('react.impulsCoach.molecules.Record.title', { recordValue, '60' })}
modifier="button"
/>
Architecture
Architecture
Create React App
Fork React Scripts
Create React App

Fork React Scripts

Fork React Scripts

Code Quality
Code Quality
Flow
Prettier
Tests
Flow

Flow

Prettier

Tests

Frontend UI
Frontend UI
Separate Repository
Frontend UI JavaScript API
UI JavaScript API

Performance
Performance
Code Splitting using Dynamic Imports
Recompose: OnlyUpdateForKeys
Sourcemap Explorer
Dynamic Imports

// Counter.jsx
import React from 'react';
import { onlyUpdateForKeys } from 'recompose';
export type CounterProps = {
count?: string | number,
modifier?: string,
};
const Counter = ({ count, modifier }: CounterProps): any => {
return (
<div className={`a-counter${modifier ? ' a-counter--' + modifier : ''}`}>
<span className="a-counter__number">{count}</span>
</div>
);
};
const shallowUpdate = onlyUpdateForKeys(['count']);
export { Counter };
export default shallowUpdate(Counter);
Only Update For Keys
Sourcemap Explorer

That's it
That's it
namics.com/jobs 😉
HSR — React @ Namics
By Dominic Modalek
HSR — React @ Namics
Slides for my Talk at the HSR Frontend Best Practices Conference 2018.
- 479