polymer-redux icon indicating copy to clipboard operation
polymer-redux copied to clipboard

Pass properties to reselect selector in statePath

Open TimPietrusky opened this issue 6 years ago • 3 comments

I'm using reselect to create a selector and use that selector in my component as the statePath. This is working fine when I can access all my data in the state.

But what if I want to use some properties from the component that need to be passed into the selector, so that it can select a specific element from the state (when the state is an array of objects and I need to select the data of a specific element in the array).

According to the documentation for reselect, you can access properties in selectors by passing them into the selector, but how can this be achieved when using the selector as the statePath?

Additional info

I'm on the https://github.com/tur-nr/polymer-redux/tree/polymer-3 branch

TimPietrusky avatar Jan 29 '18 06:01 TimPietrusky

So what I tried instead was overwriting the statePath like this:

class TimelineScene extends ReduxMixin(PolymerElement) {
  static get properties() {
    return {
      scene: Object,
      sceneAnimations: {
        type: Array,
        statePath(state) {
          // getAnimations is a selector
          return getAnimations(state).filter(animation => {
            return this.scene.animations.includes(animation.id)
          })
        }
      }
    }
  }

That works, but also gets executed every time something in the state is changing (and that might be something completely different than the data I access here). So doing it like this is too expensive in terms of performance.

TimPietrusky avatar Jan 30 '18 06:01 TimPietrusky

Hey, yes it would be a nice addition to pass the properties to reselect. So let's discuss implementation;

// ./polymer-redux.js

function compileProps(element, properties) {
    return Object.keys(properties).reduce((props, name) => Object.assign(props, {
        [name]: element[name],
    }), {});
}

// ...

const props = compileProps(element, properties);
const value = (typeof statePath === 'function') ?
    statePath.call(element, state, props) :
    get(state, statePath);

Thoughts?

tur-nr avatar Jan 31 '18 04:01 tur-nr

This looks good to me right now and I the only "side effect" I can think of would be, that also every property that is created out of the statePath would be part of props. I'm happy to test this!

Update 1

I added your implementation to my local polymer-redux.js and now I fully understand why we need the compileProps, because that is giving us the actual value of every property and not the function.

Update 2

When using the compileProps in my project I get a performance problem, but I guess this is not the problem of polymer-redux, but how I use Polymer and Redux in my render loop. I will work on improving the performance in the render loop to give you a better result on general performance issues.

Update 3

I'm using reselect now as asked in my initial comment and it's working: I can access & use the properties of the component.

Update 4

I still have the same "problem" as in https://github.com/tur-nr/polymer-redux/issues/126#issuecomment-361487860: When having more than 1 element in the selector, the statePath gets updated over and over again, even when no property is changing. But again: This could also happen because of how I use Polymer and Redux in combination.

TimPietrusky avatar Feb 05 '18 05:02 TimPietrusky