Adam L Barrett
"BigAB"
2 Ways to View Your Application
2 Ways to View Your Application
Models
Controllers
Views
Cart Component
ProductList Component
Login Component
Cart Component
ProductList Component
Login Component
Cart Component
ProductList Component
Login Component
VS
Domain
Components
UI
Components
const Documents = ({ userId }) => {
const [
{ documents },
{ create, update, destroy }
] = useDocuments({ userId });
return (
<ItemList
items={documents}
onCreate={() => create({ documentData: {} })}
onUpdate={data => update({ documentData: data })}
onDelete={document => destroy(document.id)}
/>
);
};
const ItemList = ({ items, onCreate, onUpdate, onDelete }) => {
return (
<>
{items.map(item => {
<div key={item.id}>
<Item
name={item.name}
onChange={data => onUpdate(data)}
/>
<button onClick={() => onDelete(item)}>X</button>
</div>;
})}
<AddButton onClick={() => onCreate()} />
</>
);
};
UI: UI Components (React Components)
Adapter: Domain components (also React Components)
Domain Logic/State: Stores
Adapter: Services (Class instances, functions or simple objects)
Storage: APIs and Platform (REST + GraphQL endpoints, etc)
UI Components - Function Components, Hooks, Styled Components
Domain components - Custom Hooks / Providers
Stores - RxJS BehaviorSubjects (or Redux + Redux-Observable)
Services - Simple classes that return promises or RxJS observables
APIs and Platform - GraphQL and localForage
const AlarmClock = ({ title, state, onSnooze, onDismiss }) => (
<>
<h3>{title}</h3>
<div className="display">{state}</div>
<button className="snooze" onClick={onSnooze}>
Snooze
</button>
<button className="dismiss" onClick={onDismiss}>
Dismiss
</button>
</>
);
export const CreditCardForm = () => {
const [{ values, errors, status } = {}, dispatch] = useStore(CreditCardStore);
return (
<FormComponent
values={values}
errors={errors}
status={status}
onSubmit={e => {
e.preventDefault();
dispatch(PAY);
}}
onChange={e => dispatch(UPDATE, { [e.target.name]: e.target.value })}
onBlur={e => e.target.name && dispatch(TOUCH, e.target.name)}
/>
);
};
const createStore = (action$, creditCardService) => {
const values$ = action$.pipe(ofType(UPDATE), map(creditCardService.validate));
const status$ = action$.pipe(
ofType(actions.PAY),
exhaustMap(({ values }) => {
from(creditCardService.pay(values)).pipe(
mapTo({ status: 'success' }),
catchError(error => of({ message: error.message }))
);
})
);
return combineLatest(values$, errors$, status$, (values, errors, status) => ({
values,
errors,
status
}));
};
class creditCardService {
construtor({ apiUrl }) {
this.apiUrl = apiUrl;
}
async pay(data) {
const response = await fetch(this.apiUrl, { body: JSON.stringify(data) });
return response.data;
}
async validate(ccData) {
await checkValidNumber(ccData);
checkIsExpired(ccData);
}
};
npx create-nx-workspace myorg
npx create-nx-workspace myorg
npx: installed 180 in 7.764s
? What to create in the new workspace
angular [a workspace with a single Angular application]
angular-nest [a workspace with a full stack application (Angular + Nest)]
❯ react [a workspace with a single React application]
react-express [a workspace with a full stack application (React + Express)
]
next.js [a workspace with a single Next.js application]
(Move up and down to reveal more choices)
...
cd myorg
apps directory
libs directory
import { libraryModule } from '@myorg/library-name'
npx nx list
Designer and Developers create a single source of truth and common language for UI components across products and applications
Pro-Tips:
npx nx g @nrwl/react:library design-system --directory ui
Generate Libraries
npx nx g @nrwl/react:component SuperButton --project ui-design-system
Generate Components
npx nx g @nrwl/react:storybook-configuration my-shared-react-lib
npx nx g @nrwl/react:redux products --project store
Generate Redux Slices
npx nx g @nrwl/workspace:lib ProductService --directory services
Generate Sevices
npx nx dep-graph
nx affected:test
nx affected:build
npx nx e2e my-app-e2e
nrwl.io
github.com/BigAB/enterprise-react-example