Double data binding with Redux + React

Date 12 juillet 2016 Catégories Developpement par VulgaireDev

The double data binding is something more common with Angular js than with React and Redux, because the flux pattern is a "one way data binding". But sometimes you'll need it (or at least it is the simplest way of doing the job).

What is this "double way data-binding" ?

The double way data-binding means that in your application, a modification of the view (the UI if you prefer) implies the modification of the model (or the Store, if we talk with the Redux language), and inversely, a modification of the model implies the modification of the view.

Mathematically speaking, we have a double implication, so there is an equivalence between the model and the view (for the datas).

\(UIModification \implies StoreModification\)

and

\(StoreModification \implies UIModification\)

so :

\(UIModification \equiv StoreModificaton\)

Conclusion: in a double way data-binding, the datas of the UI and the ones of the Store are always the same, and the modification of one implies the modification of the other.

Why do we need that ?

For instance, I am working on an application wich let the user make REST calls. He can specify the current URL he wants to call, so there is a field "URL". I need this url when the user clicks on the "GET" button.

If it is all I need, a classic redux action would be enough : we dispatch an action "SET_CURRENT_PATH" each time the url field is changed, and the store will change.

But what if another component changes the current path ? The URL label will not be up-to-date !

 

In fact, I also want the URL field to update when the user clicks on some links (because I have some links that make directly a REST call) ! That is why we need a double way data binding here.

This way we are good, if we hide the complexity of Redux (unnecessary here), we have this :

 

How to code it ?

{/*actionIndex.js*/}

export function setCurrentQueryPath(currentPath) {
  return {
    type: 'SET_CURRENT_QUERY_PATH',
    currentPath: currentPath
  }
}
{/*reducerIndex.js*/}

const reducer = (state, action) => {
    switch (action.type) {
        case 'SET_CURRENT_QUERY_PATH':
            return {
                ...state,
                currentPath: action.currentPath
              }
        default:
            return state
    }
}

export default reducer

 

{/*  InputCurrentPath.js */}
import React from 'react';
import { connect } from 'react-redux';

import * as actions from '../actions/actionIndex.js';

class InputCurrentPath extends React.Component{
  updateCurrentPath = (e) => {
    {/* We map the URL field to the currentPath of the store*/}
    this.props.dispatch(actions.setCurrentQueryPath(e.target.value));
  }
  render() {
    return (
      <input className="myurl" value={this.props.currentPath} type="text" onChange={this.updateCurrentPath}/>
    );
  }
}

{/* We map the currentPath of the store to the URL field*/}
const mapStateToPropsInputCurrentPath = (state/*, props*/) => ({
    currentPath: state.currentPath
})
export default InputCurrentPath = connect(mapStateToPropsInputCurrentPath)(InputCurrentPath);

Here we are, I hope this helped you !

(if you see some mistakes let me know, I am not a native english speaker !)

Commentaires

blog comments powered by Disqus