Redux and ReactJS integration
*****************************
The `React-Redux `__ library can be used to connect the Redux application state to ReactJS components.
This can be done in the following way:
* wrap the ReactJS root component with the ``react-redux`` **Provider** component, to bind the Redux store to the ReactJS view.
.. code-block:: jsx
React.render(
{() => }
,
document.getElementById('container')
);
* explicitly connect one or more (smart) components to one or all parts of the state (you can also transform the state and have computed properties) with the function ``connect``.
.. code-block:: jsx
// react functional component
function AppComponent(props) {
return (
{props.title}
{props.text}
);
}
// connect the component using the ``connect`` function
const App = connect(function(state) {
return {
title: state.title,
text: state.name + '.' + state.surname
};
})(AppCmp);
The connected component will receive the ``title`` and the ``text`` properties, valorized with respectively with ``state.title`` and ``state.name + '.' + state.surname``.
so if the state has this shape:
.. code-block:: json
{
"title": "Author",
"name": "John",
"surname": "Smith"
}
The final resulting HTML will be
.. code-block:: html
Author
John.Smith
.. todo:: handlers. Provide handlers properties example for connect function
Connect function
----------------
Let's see more in detail the `connect `_ function we used before.
.. code-block:: javascript
connect(mapStateToProps, mapDispatchToProps)
Calling this function will return **another function**.
This function returned can be used to *transform* a component in a new *smart component* connected to the state, that is able to show
values from the state and dispatch actions to modify it.
.. code-block:: jsx
const Cmp = (props) =>
{props.name}
;
const hoc = connect(mapStateToProps, mapDispatchToProps);
const NewCmp = hoc(Cmp); // this returns the new component connected to the state
React.render(
{() => }
, document.body);
.. note::
Functions that gets a React Component as argument and return another react component, typically enhanced are often called **Higher Order Component, (HOC)**
Connect function has more argument and many options, but we are interested only to the fist two:
- ``mapStateToProps`` is a function that gets the redux state as parameter and returns the props to pass to the components (as JavaScript object, ``{propName: propValue}``).
- ``mapDispatchToProps`` can be an object or a function. It is used to dispatch actions from the component, passing some functions to call as props to the react component.
**mapStateToProps example:**
.. code-block:: javascript
// reducerName can be the one used in mapstore i.e.
// controls,catalog,annotations,maptype etc.
const mapStateToProps = (state) => {
propertyName: state[reducerName].property,
propertyName2: state[reducerName2].property2,
};
The faster and easiest way to use ``mapDispatchToProps`` is to pass an object like this
.. code-block:: javascript
const mapDispatchToProps = {
propertyName: actionCreator
};
The ``connect`` function will pass to the component a
.. code-block:: jsx
// reducer.js
function reducer(state = {count: 0, action) {
case "INC":
return {count: state.count +1};
default:
return state;
}
.. code-block:: jsx
// actions.js
function inc() {
return {type: "INC}
}
.. code-block:: jsx
// Counter.js
/**
* Button that gets 2 properties
* - count, shown in the button text
* - onClick, called when the user clicks on the button
*/
const Cmp = (props) => {
return
()
};
// this function maps the global state ``count`` to the property ``count``.
const mapStateToProps = state => {
return {count: state.count}
};
// this maps the function inc, to the property onClick.
const mapDispatchToProp = {
onClick: inc
};
// This returns an enhanced component, connected to the state.
// it will dispatch ``inc`` on the redux store.
export connect(mapStateToProps, mapDispatchToProp)(Cmp);
Final schema
------------
In the following figure we can summarize the system, giving names to some parts.
.. figure:: img/react-redux.jpg
:alt: react redux
:align: center
React & Redux connection
- **Action**: the object that represents the change of the state. has a ``type`` property that identifies it
- **ActionCreator**: Function that returns an action. Useful to define a common interface to create actions.
- **Reducer**: function that gets an action and the current state and returns the new state
- **Store**: Object that keeps the application state and gives the methods to dispatch actions (and so update the state) and to access to the state (``getState()``)
- **Selector**: Utility function that takes the whole state (returned by ``store.getState()``) and returns derived information (e.g. a sub-part of the state, or a calculation). They are very useful to define a common interface of accessing to the state.
- **Container**: Component connected to the state with ``connect`` function. This receives props and automatically re-renders when some updates are applied to them.
- **Template**: represents the whole nested structure of components that will re-render to update the virtual DOM, and then the real DOM.