/* The original problem * We needed a way to specify props which were only available in certain modes. To do so manually, we would call connect and manually do some * merging: */importReactfrom"react";import{connect}from"react-redux";import{Mode}from"app/reducers/app";constInput=(props)=><input{...props}/>exportdefaultconnect((state,props)=>{constmode=state.app.get("mode",Mode.Display);returnR.merge(props,R.propOr({},mode,props.modeProps));})(Input);/* * In the above, we are saying to combine the original props with those found in modeProps for the particular mode. This gets tedious when you * want to mess with more than modes, as you need to make sure futher prop manipulations act on the new mode-specific props, rather than the * original. */
/* connectWithMode to the rescue...I thought * The idea here was that if we had a version of connect that automatically merged in mode-specific props, * we could save a lot of boilerplate and clean up some things. */importReactfrom"react";import{connectWithMode}from"app/utils/redux";import{Mode}from"app/reducers/app";constInput=(props)=><input{...props}/>exportdefaultconnectWithMode()(Input);/* * While this is less boiler-platey, it comes at the cost of not being able to do further modifications of props that require access to state. * You see, mode-specific props aren't available until *after* connectWithMode returns. Thus, this function will receive all the original props, * not those that resulted from taking mode into consideration: */constmapStateToProps=(state,props)=>{// If this function is passed to connectWithMode, the props referenced will be the original props, not the ones transformed by modeProps};/* * As such, you have to do prop manipulation in a life cycle method or manually construct mode-specific props within mapStateToProps, which is * both redundant and undermines the purpose of having connectWithMode. */
/* In the future * What we really want is the access to mode-specific props that the original provides, with less boilerplate, but without the restrictions * imposed by connectWithMode */importReactfrom"react";import{connect}from"react-redux";import{modeProps}from"app/utils/redux";importRfrom"ramda";constInput=(props)=><input{...props}/>exportdefaultconnect((state,props)=>{constappState=state.app.toJS();// the location of mode changed recentlyconst{mode}=state.components;constnewProps=modeProps(mode,props);returnnewProps;})(Input);// If we need to do further manipulation, doing so is now trivialconstmapStateToProps=(state,props)=>{constappState=state.app.toJS();const{mode}=state.components;constnewProps=modeProps(mode,props);const{source,inputKey}=newProps;returnR.merge(newProps,{sourceValue:R.path(source,appState),inputValue:R.path(inputKey,appState)});};/* * While destructuring props and state may seem boilerplatey, a few things should be noted: First, I intend to eventually get rid of * Immutable.js, which will make the `state.app.toJS()` line go away and allow me to instead say `const {app} = state`. Second, once * state is a plain old JavaScript object, we could pass them inline if we wanted to instead of destructuring */
Comments (0)
HTTPSSSH
You can clone a snippet to your computer for local editing.
Learn more.