Git Product home page Git Product logo

Comments (7)

MicheleBertoli avatar MicheleBertoli commented on May 22, 2024

Thank you very much for opening this issue, @angeloashmore.

The decision of using the context was a trade-off, as it presents some limitations.
For example, putting a component that returns false from shouldComponentUpdate anywhere in the tree breaks the subcomponents (<State /> and <Action />) as well.
Potential solutions are using react-broadcast or waiting for the new context API.

In the meanwhile, as you suggested, using a key would solve the issue of the nested state machines (PR anyone? :)).

Would you mind providing more information about your use-case?
I'd love to understand the problem you are trying to solve with nested (disconnected) state machines.

from react-automata.

angeloashmore avatar angeloashmore commented on May 22, 2024

I created a reusable component that uses a statechart (it was an asset preloading component, so really simple states: init, loading, loaded, failed).

When I tried to use that component within a larger component that also uses its own statechart (specifically a Gatsby page), I noticed things weren't working anymore. 😄 I've since replaced the statechart with a few flags.

In other words, if someone were to create a reusable utility component or HOC that utilized a statechart for its own internal logic, it could break a user's own statechart use. Using statecharts and xstate is new to me, so feel free to let me know if this doesn't sound like a good usecase.

I believe react-redux has multiple store functionality using keys, so maybe something similar could be implemented?

See: https://github.com/reactjs/react-redux/blob/9434e4389809b5c5ab707571e07e4e5f01562087/src/components/Provider.js#L22

from react-automata.

MicheleBertoli avatar MicheleBertoli commented on May 22, 2024

Hello @angeloashmore, I implemented a solution and it seems to work (example).
It uses the statechart's key to identify the machine, and it's possible to "connect" to a particular one setting the channel prop on the components.
It'd be great if you could try it yarn add react-automata@next
Thank you very much!

from react-automata.

angeloashmore avatar angeloashmore commented on May 22, 2024

Works great! Thanks for taking the time to write this.

I just noticed two things and am wondering what your thoughts are:

  • If Action or State is given a channel prop, but no statecharts contain the given key, the component throws the following:

    TypeError: Cannot read property 'machineState' of undefined
    
    shouldShow
    node_modules/react-automata/lib/State.js:41
      38 | 
      39 | var shouldShow = exports.shouldShow = function shouldShow(props, context) {
      40 |   return matches(props.value, context.machineState);
    > 41 | };
      42 | 
      43 | var shouldHide = exports.shouldHide = function shouldHide(props, context) {
      44 |   return !matches(props.value, context.machineState);
    

    It might be helpful for the user to receive a message describing the missing channel?

  • From a developer experience perspective, ideally I wouldn't have to set a key for every State or Action call for my app and instead push that requirement to utility/HOC components.

    <MyComp>
      <UtilComp>
        <State value="myCompState1">{/* ... */}</State>
      </UtilComp>
    </MyComp>

    MyComp: A component wrapped with withStatechart (no key)
    UtilComp: A component wrapped with withStatechart (with key), probably installed from NPM

    Currently, the above would not work since State is referencing UtilComp's statechart, not MyComp. This would be tricky to solve since State would need to "jump" past the keyed statechart and find the first non-keyed statechart to compare values.

    • Is it worth the effort/complexity to implement?
    • Or should users key everything and maybe write their own wrapper:
      const MyCompState = props => <State channel="myCompStatechart" {...props} />

from react-automata.

MicheleBertoli avatar MicheleBertoli commented on May 22, 2024

Thank you very much for your feedback, @angeloashmore.

re: error messages
I added a couple of invariants with meaningful error messages. I was also planning to add a few more in different parts of the library.

re: context
In the first iteration, I was actually using the approach you described (getting the "default" context when there's no key). However, that would force to set the "channel" even for a single statechart with a key.
Given your use case, and a few other cases I'm considering, I decided to add a channel option to the HOC so that it's now explicit when a new communication channel is created. In all the other scenario, the components receive the "default" context.
I updated the example as well, which should now reflect your use case.

yarn add react-automata@next will give you the new version.

from react-automata.

angeloashmore avatar angeloashmore commented on May 22, 2024

This works exactly as expected now. I love how simple the API of this library is, even with all the power it has. Thank you so much, I really appreciate it.

from react-automata.

MicheleBertoli avatar MicheleBertoli commented on May 22, 2024

Thank you very much one more time, @angeloashmore.
I just published v1.2.0 with channels support, thanks to your feedback 🙌

That's how React and Statecharts are: simple and powerful.
They work very well together.

from react-automata.

Related Issues (20)

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.