Git Product home page Git Product logo

recompact's Introduction

Recompact

Build Status codecov

Recompact is a set of React higher-order components for reactive programming. It's a drop-in replacement of Recompose with several enhancements.

State of recompact

React has introduced React hooks: a new way to manage state and lifecycle in React. It solves most of use case that recompact was trying to solve. That's why recompact is now deprecated and not actively maintained. The project will remain published on npm but it does not accept new issues and it won't evolve any more. If you use it, you are encouraged to migrate to hooks, if you don't use it yet, then do not install it. If you really like it, feel free to fork it!

Installation and Usage

To install the stable version:

yarn add recompact

and to use it in your code:

import recompact from 'recompact'

Optimizing bundle size

The best way to reduce build size is to use babel-plugin-lodash. It can be used with other libraries than lodash, just like this:

.babelrc

{
  "plugins": [
    ["lodash", { "id": "recompact" }],
  ]
}

Transforms

import recompact from 'recompact'
import { pure, withProps } from 'recompact'

const enhance = recompact.compose(
  withProps({ className: 'beautiful' }),
  pure,
)

roughly to

import _compose from 'recompact/compose'
import _pure from 'recompact/pure'
import _withProps from 'recompact/withProps'

const enhance = _compose(
  _withProps({ className: 'beautiful' }),
  _pure,
)

Tree shaking

Since tree shaking isn't ready yet to reduce build size efficiently, it is not supported in recompact.

Recompact vs. Recompose

Recompact is a drop-in replacement* for Recompose with better performance.

* Except for the callback of withState's state updater.

Flattened React components tree

You may have noticed the "compact" keyword in "Recompact". It's the main differences between Recompose and Recompact. Recompact compacts all higher-order components into a single one. It results in a flatter React tree. A flatter React tree has several advantages: performance improvement, better debugging (especially in React Developer Tools) and easier testing.

Let's take two components using composition, one using recompose and one using recompact.

The two components are similar, but if you take a look at the React component tree (using React Developer Tool), you can see that the component using recompact is flat:

recompact-vs-recompose

New methods

Recompact also features higher-order components that are not included in Recompose:

And some very specific higher-order components that give you a lot of power:

To learn more about how to use connectObs and withObs inside your project, please refer to this complete guide about connectObs and withObs.

License

MIT

recompact's People

Contributors

arian-woopra avatar craga89 avatar gregberge avatar helixbass avatar ipanasenko avatar matthieuprat avatar oliviertassinari avatar vannayer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

recompact's Issues

withPropsOnChange doesn't execute when the given props are undefined

Here's a little code snippet to demonstrate the problem:

import cc from 'classcat';
import {withPropsOnChange} from 'recompact';

export default function className(klass) {
    console.log('helllo',klass);
    return withPropsOnChange(['className'], ({className}) => {
        let tmp = klass || className;
        console.log('TTTTTTTTMPPPPPPPPPPPPP',tmp,klass,className);
        if(tmp) {
            return {
                className: klass && className
                    ? cc([klass,className])
                    : tmp
            }
        }
    });
}

When className is undefined, recompose will print "TTTTTTTTMPPPPPPPPPPPPP" but recompact will not.

i.e., recompact doesn't execute the function when shouldMapOrKeys refers to undefined props.

I understand why it may have implemented this way -- normally when using this HOC you're computing a new value from the old value, and if the old value is undefined the new one usually will be too -- but in this case I still want it to run.


Edit: Actually, I don't know what's going on. It looks like this should unconditionally execute, but it doesn't. All I know is the behaviour is different between recompose and recompact.

withState updater doesn't invoke a state changing callback

hi.

abstract part of my real code:

compose(
  withState('status', 'setStatus', {}),
  withProps(
    ({ setStatus }) => ({
      go(key) {
        setStatus((prevState) => ({
          ...prevState,
          [key]: true
        }), () => console.log('done!'));
      }
    })
  )
)(Test);

no log. but it works fine with HOCs imported from recompose.

Fix connectObs

It should not trigger "undefined" if it's not necessary.

Why Isn't Compose Importable?

The first example on your front page is:

import recompact from 'recompact'
import { pure, withProps } from 'recompact'

const enhance = recompact.compose(

To a library outsider (especially one coming from recompose where compose is just another import) that looks weird: why isn't it simply:

import { compose, pure, withProps } from 'recompact'

const enhance = compose(

?

At the very least ES6 syntax allows for combining those two lines into one:

import recompact, { pure, withProps } from 'recompact'

But since these are literally the first lines of code a newcomer to your library will see, it might be be nice if you could just add a one-line comment or something to explain why such a functionally-focused library requires compose to be imported/used as a method rather than as a stand-alone function.

Flow type support?

Hi, can we simply use the types of Recompose or does this library needs its own set to properly support Flow?

Thanks.

HOCs not being compacted

Hello, I tried substituting recompose with this, and everything works great so far except for the HOCs not being compacted:

recompact

Here's what I'm doing to my component:

export default compose(
  setDisplayName('Home'),
  connect(mapStateToProps),
  lifecycle(spec),
  withHandlers(handlers),
)(Home);

Everything is imported from recompact and I even removed recompose so it can't be that. Did I miss something? Oh and I'm using the latest version 2.3.2

Bugs when surrounding HOCs that hoist statics

On the current project, we ran into mysterious bugs when placing two react-apollo graphql() HOCs in the same compose() chain. Turned out that because each was followed by a withProps() (ie compose(graphql(), withProps(), graphql(), withProps())) and graphql() uses hoist-non-react-statics to hoist statics, bugs were because graphql() was hoisting the "internal" symbol statics that recompact uses to identify other components as fellow "compactable" Recompact HOCs, so withProps() thought that graphql() was another Recompact HOC that it could condense or whatever (at least this is my understanding)

So my solution was to fork recompact to export the symbols it uses as keys for static properties (opened #95) and fork react-apollo to accept a blacklist of keys not to hoist (which can then be passed the exported recompact symbols)

However, then this week ran into the same issue using a different HOC (withNavigation() from react-navigation) which also hoists statics using hoist-non-react-statics. So hoping there's a better approach than trying to get various third-party HOCs to accept a hoist blacklist. This feels at this point like a flaw in the way recompact identifies other recompact HOCs, since it's considered best practice for HOCs to hoist statics (which to my understanding then causes bugs whenever it sits between two recompact HOCs), but not sure if there's another mechanism besides statics that recompact could use to identify other recompact HOCs?

Peer dependency

I'm seeing the following warnings

warning Unmet peer dependency "rxjs@^5.0.0-beta.10".
warning Unmet peer dependency "rxjs@^5.0.0-rc.4".

I think that we can increase the peer dependency scope.

IE 11: 'Symbol' is undefined

UPD: PR is here #99


'Symbol' is undefined throwed by node_modules/recompact/utils/createCompactableHOC.js in IE 11.

Bundled version of createCompactableHOC:

"use strict";


exports.__esModule = true;

var _createHOCFromMapper = __webpack_require__("./node_modules/recompact/utils/createHOCFromMapper.js");

var compactable = Symbol('compactable'); /* eslint-disable no-param-reassign */

var isCompactable = function isCompactable(Component) {
  return typeof Component === 'function' && Component[compactable];
};

exports.default = function (createCompactableComponent, createComponent) {
  return function (BaseComponent) {
    if (isCompactable(BaseComponent)) {
      BaseComponent = BaseComponent[compactable];
    }

    var Component = createComponent(BaseComponent);
    Component[compactable] = createCompactableComponent(BaseComponent);

    if ((0, _createHOCFromMapper.isMapperComponent)(BaseComponent)) {
      return Component[compactable];
    }

    return Component;
  };
};

Add all missing utilities from recompose

  • getDisplayName
  • wrapDisplayName
  • shallowEqual
  • isClassComponent
  • isReferentiallyTransparentFunctionComponent
  • createEagerElement
  • createEagerFactory
  • createSink
  • componentFromProp
  • nest
  • hoistStatics
  • setStatic
  • setPropTypes
  • setDisplayName
  • toClass
  • utils/pick
  • utils/omit
  • utils/createEagerElementUtil

include some benchmark results

Since the README mentions that there is some improvements in performance over recompose, it would be nice to provide those in the README or at least in a linked document so people could see them without needing to install and run them for themselves.

Knowing the relative scope of the performance improvement is key for people to know if that is a relevant factor.

Cannot use Symbol as key with `withContext`

const $yolo = Symbol('yolo')

compose(
  withProps(() => ({ [$yolo]: 123 }),
  withContext(
    { bolos: PropTypes.number }, 
    ({ [$yolo]: x }) => console.log(x) || x, // undefined
  ),
)

Is 3.3.0 released?

Hey guys. I see v3.3.0 was created a couple days ago, but I got v3.2.1 from npm. Can someone have a look why is this so?

Specifically, I expected withStateHandlers to be available, as I try to replace recompose with recompact

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.