I use Preact and preact-redux, with an immutable state.
I have a PictureList component connected to the state, and the props are updated. (I log nextProps in componentShouldUpdate() and in render())
When I start the app PictureList is empty, then I receive a list of ID and I print one component (Picture) by id (with map)..
The render() function of my PictureList component is called after the state update, but.. the DOM is not updated, and the components of the list are not mounted (Picture componentDidMount is never called)
I have no errors, I use ES6 Component, and preact-compat. When I switch to react everything work as expected.
I think there is a link with the immutable state because when I pass an array instead of an immutable List to the props, the DOM and the Picture's component are mounted.
I didn't found any discussion on the use of immutable with Preact, so I'm not sure if someone already had this problem and can point me to a solution..
Hi @delta-9 - you're right, there is likely a compatibility fix needed here to account for Immutable.js. I have seen this issue come up previously but nobody has yet asked for a solution. Right now Preact doesn't do anything special to account for immutable's objects. I've never actually used it, so I'll probably have to do some digging to figure out what the most logical approach would be to handle this transparently. It might be as simple as automatically unboxing (.toArray()?) children in preact's h() method. If the size is large enough, I would imagine this feature would end up in preact-compat.
To push this forward, I made a repo with a simple step to reproduce the issue. The main component print two component connected to redux. One get an Immutable List, the other get the List as array(). (the computation happened in the mapping in connect()).
Also I use babel aliasing to use preact instead of react.. (so the import look like it's react but not)
to use it simply do
npm i then npm run start
There it is : https://github.com/delta-9/testPreact
I added two test case to the repo, it seems that simply if you pass an Immutable object to a component, this one doesn't render... (however render() is called..).
@developit thank you for your help on this
Awesome work @delta-9. Looks like the child iteration is failing, which is expected.
For the array casting, is there a generic method that is generally used to get the raw JS value for an Immutable type?
I commit a new branch that use react with the same code
Here with preact : http://plumber-monkey-66073.netlify.com/
Here with react : http://dentist-cinderalla-46277.netlify.com/
You can see in the log there is something strange the "List" value is casted to a strange type "Ut" : just compare the log of both builds.
To cast any Immutable value to the JS value you can do myvar.toJS()
But if I don't receive the Immutable version via the props, Immutable became useless (I can't do comparison of deep object for cheap)
The cast would happen in Preact's diff, so only for Elements, not your components. props.children would still be an Immutable List.
This didn't quite make the cut for 6.0.0 (now in beta) due to time constraints, but I'm looking into it for 6.1!
I moved this comment to a PR regarding this work.
see https://github.com/developit/preact/pull/476#issuecomment-280424862
@delta-9 - The link to the original test case is broken (see
https://github.com/delta-9/testPreact). Do you still have the code around in some form that you can post?
From a quick read of the code it looks to me like Preact 10 still requires children to be either an object or an Array.
Sorry for that 馃槙 I might have deleted this repo upon an OCD crisis 馃樄 and I don't have it anymore.. the laptop I used at the time is in a stonegrave馃拃 ..
Closing, because the code from the original issue was lost :slightly_smiling_face:
Most helpful comment
This didn't quite make the cut for 6.0.0 (now in beta) due to time constraints, but I'm looking into it for 6.1!