gaearon / react-side-effect

Create components whose nested prop changes map to a global side effect

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Integration with Fluxible

edygar opened this issue · comments

How can my side effect execute an FluxibleAction? Since there is no bind to context, I couldn't achieve this. In my case, I'm doing a component called TitledScreen which could be used at any point of my component tree and TitledScreen should join the given titles in the right order and them execute an FluxibleAction, but onChange has no context.

@edygar could the FluxibleComponent help in your case? Or just passing the context as prop?

FluxibleComponent has no effect over onChange callback, since it has no references to sideEffectComponent instance. Passing context as prop would be an option, but it seems odd to me.

if onChange be bound to the sideEffect resulting component, it solves and allows calling instance methods.

commented

Let's reimagine it as <SideEffect onChange={} /> component instead. Then you'll have your own wrapper that can use the context in its internal handleChange method.

Would you like to take this?

For sure! That would be great and very interesting, but how changes were going to be detected?

commented

I haven't thought this through, so I can't say :-). I think it should work similarly to how it works now, but without mixin parameter and using composition instead.

This way something like

var BodyStyle = createSideEffect(function handleChange(propsList) {
  var style = {};
  propsList.forEach(function (props) {
    Object.assign(style, props.style);
  });

  for (var key in style) {
    document.style[key] = style[key];
  }
});

becomes something like

class BodyStyle extends React.Component {
  // you can declare propTypes, contextTypes here

  render() {
    return <SideEffect {...this.props} onChange={this.handleChange} />;
  }

  handleChange(propsList) {

    // since it's a proper component, you can access context
    // here if you like!

    var style = {};
    propsList.forEach(function (props) {
      Object.assign(style, props.style);
    });

    for (var key in style) {
      document.style[key] = style[key];
    }
  }
}

I think making react-side-effect context aware is key. With so many large React apps making use of Flux architectures, and nearly every Flex architecture making heavy use of Context in order to stay Isomorphic, I think that a clear integration with Context is the path forward.

commented

@duro It should be easily possible to make it context-aware if refactored as I described above.

@gaearon When I try this, I get the following error

[Error: Invariant Violation: onChange(propsList) is a required argument.]

Here is a gist of my approach:

https://gist.github.com/duro/88d5f2cb054ddd8f9c41

Do you have a working example of this approach that does not reply on ES6 Classes? I am trying to implement this, and it seems to be fighting me at every turn.

@gaearon, I've just tried to implement SideEffect using context to propagate methods from the root to branch instances of SideEffect, so they could communicate as soon as life cycle methods was called, but turns out the context isn't propagating, not until React 0.14 I guess, contexts are really hard to get as they have no doc. Anyway, If anyone has any interest to solve the problem, here follows what I've got https://gist.github.com/edygar/7080b548290f5c3747db

commented

@duro

When I try this, I get the following error

Sorry, I should have been more clear. That's the new API I propose. Turning SideEffect to a component from a factory as it is now. It's not implemented so nope, you can't use it unless you also implement it ;-)

@edygar

Yeah, this makes sense. In 0.14, context will use the parent tree so your example should probably work in 0.14 (and maybe master too?).

commented

React Side Effect is now a higher-order component.