Home

React content management Framework

This is a framework to help you to build configurable React App.

It provides a set of base APIs and patterns.

Travis CI NPM dependencies devdependencies

Requirements

Before trying CMF you must know:

You must understand all the following words: pure component, action creator, reducer, put, takeEvery, fromJS, ...

What is react-cmf

It's a framework. It is the results of the years of experience with react ecosystem at Talend. The goal is to provide one way to do the things keeping best pratices in mind.

Working with react-cmf

If you tried to work with the required addons listed above you will do some repetitive tasks and some boiler plate every time and on each components.

When working with a framework like angular you have the tools plus a guideline on how to use them. With CMF the idea is the same. Provide the good set of tools plus the guideline.

To start a project using react-cmf you can use bootstrap API.

Working with react-cmf means:

  • you write a set of configurable pure component connected using cmfConnect
  • you configure them using the settings
  • events are handled in a saga (effects are the way to write business code)

diagram rendering cycle

Side by side with angular 1:

  • components are React cmfConnected (pure) component
  • services are sagas
  • controllers are containers

UI sends actions into redux which are handled by sagas.

cmfConnect higher order component

cmfConnect create a component with all CMF features charged in it. Under the hood it uses the connect function and create a container.

Once your component is connected:

diagram cmfConnect

Read more about cmfConnect

Store structure

CMF uses react-redux store with the following structure

  • root
    • cmf
      • collections
      • components
      • settings

Collections and components use Immutable data structure.

ComponentState Management

Component state can be easily stored in cmf state, each are identified by their name and an unique key, so component state can be stored and reused later.

We give you the choice to use either:

  • CMF redux state (this.props.state && this.props.setState)
  • React component state (this.state && this.setState)

Warning: you should use the redux state except for part that require lots of mutation without sharing. For example for Forms you should prefer to use the internal React component state.

Collections management

Manage a local cache of your business data. You can connect your component to give it access to your data and being able to dispatch action to let CMF reducers write them.

You can dispatch some actionCreators in api.actions.collections for that.

Settings

We don't want to create a PR, merge, build to change a label of a button right? With CMF you can describe all your app just using json.

The json looks like this:

{
	"props": {
		"App#default": {
			"saga": "bootstrap"
		},
		"Navbar#default": {
			"brand": "Talend",
			"left": [{ "component": "Button", "componentId": "help" }]
		},
		"Button#help": {
			"id": "help",
			"label": "help",
			"payload": {
				"type": "MENU_HELP",
				"cmf": {
					"routerPush": "/help"
				}
			}
		}
	}
}

Scripts

When you have cmf in you project, it adds scripts in your node_modules/.bin

Tips you should add node_modules/bin folder into your path.

So you can use them either in CLI or in npm scripts.

Tests & mocks

When you are in the context of CMF and you want to test your component you will need to mock some stuff (context, ...).

We want testing experience to be easy so CMF provides some mocks for you.

import React from 'react';
import { Provider } from 'react-cmf/lib/mock';

import { render, screen } from '@testing-library/react';

import AppMenu from './AppMenu.component';

describe('AppMenu', () => {
	it('should render', () => {
		render(
			<Provider>
				<AppMenu />
			</Provider>,
		);
		expect(screen.getByRole('button')).toBeDefined();
	});
});

This way MyComponent may request for the following context:

  • registry
  • store

you may change the following using simple props:

  • store
  • state
  • registry

The http saga

The http saga is here to help execute some http requests from inside any saga.

By default, the credentials option of fetch is set to includes and not the default same-origin. It allows to share the credentials (cookies) in cross origin requests.

See credentials in the fetch() global function for more details.

More

Internals