idibidiart / react-native-responsive-grid

Bringing the Web's Responsive Design to React Native
Other
379 stars 42 forks source link

Keeping state when Grid is unmounted (for nested Grids) #31

Closed idibidiart closed 6 years ago

idibidiart commented 6 years ago

I've not used this grid in any project recently.

However, the fact that some of you are using it has prompted me to think more about extending its dynamics and patterns, with special thanks to @peacechen

Proposal to enable Nested Grids

The Grid component is responsible for encapsulating state and updating the children. Children can read state as well as setState on Grid allowing them to re-render the component tree. In addition, layout changes captured on the Grid component via the React Native onLayout event cause re-rendering of the Grid children with updated layout information.

The Grid component pattern was borrowed from a tweet by Tanner Lindsay and then I toyed with the idea of exposing lifecycle methods as props (that reference the lifecycle handlers) so that you can tell the Grid what to do when it mounts, unmounts, etc, just as Ryan Florence does in his Component component pattern (which is also based in part on what Tanner had originally shared) but realizing that when Grids are nested a child Grid may get unmounted in which case it will lose state, and when it loses state it will do everything you tell it to do in those life cycles starting from scratch, so if it had fetched some data in component did mount then that data will be gone (all state will be gone) when it's unmounted and it has to get that data again. More importantly, it will lose other state, like visual state. So I opted to keep the Grid as the root component and I had even introduced logic to prevent nesting of Grids (removed later)

To make a long story short, what I'm proposing is to store the state in an outer scope where each nested Grid has a lens into the part of global in-memory state that belongs to it. This way when a child Grid is unmounted it can check its state and rehydrate from it or updated it with live data when needed.

Just putting this out in case I'm missing something. I'll get to it at some point.

Also, happy to take PRs for any of the proposals.

peacechen commented 6 years ago

Nested grids would be powerful. Implementation would be complicated, and thus maintenance would be harder.

State persistence could be done with Redux. The advantage is that it'll work with any version of React / RN. Disadvantage is it adds a dependency that is somewhat complex.

Another option could be React's new Context API. It's lighter weight, but requires React 16.3+, so this library would break compatibility with older versions.

Looking forward to your updates.

idibidiart commented 6 years ago

The Context API could be a great idea. i have to dig into it. Is React 16.3 in latest RN?

But I have a simple scheme in mind:

We would still use the component’s local state and its own setState but upon componentWillMount we copy over the state from a state object that is declared outside the component’s scope (in global scope) and upon componentWillUnmount we do the opposite (copy component’s local state to the state object in the global scope)

We could use an XPath like string as the key. The path thru the UI component tree to the component (including the index in case of a node containing n component’s of the same display name) could be used as the key in the state object. This way each component will be able to access its shadow state in the global state object after mounting and re-mounting.

So it’s not complicated this way.

We could also code a Haskell style lens function to make the global state object immutable but that would be a later stage optimization.

Thoughts on this?

peacechen commented 6 years ago

React 16.3.2 is the current stable release.

I'm interested seeing how you implement this. It feels like global state should be handled by the framework, otherwise we're reinventing the wheel. But if it's kept bare bones simple it might be worthwhile.

idibidiart commented 6 years ago

True.

Let me look into the Context API. It might make it 10X simpler to maintain that way.

idibidiart commented 6 years ago

I should have some time to work on this next week...

At work, I'm switching to Angular Elements for Web Components development (see e.g. https://github.com/idibidiart/web-components-with-ai) , and I'm curious about Google's Flutter which competes with React Native.

However, React Native has a pretty strong ecosystem so I'm trying to keep this project going.

If you feel like submitting a PR I can advise on it and let you handle the whole thing.

It would be also very interesting to see what parts of display:grid behavior we could introduce out of the box.

@peacechen

peacechen commented 6 years ago

Flutter and Angular Elements look interesting, if not late to the party. Will be worth keeping an eye on them to see how much traction they get in their respective niches.

TBH this isn't on my radar at the moment because I don't expect to use it in our app yet. The layouts we use aren't super-complicated, and I hope they don't get much more complex 😉