-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
React + Immutable.JS: Best practice for sending Immutable.Map as props to children components? #667
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
posts.values().map(post =>
<PostComponent post={post} key={post.get('id')} />
) I don't know if you'd need to append an |
@eyston Thanks for the help! 👍 Yeah, it's posts.valueSeq().map(post =>
<PostComponent post={post} key={post.get('id')} />
) I guess I'm still a bit confused at to what an |
I don't know of one. I came from clojure so I just guess a lot when it comes to Immutable.js :). I'm actually not sure why so many functions have a Guessing from clojure ... |
@eyston Thanks for the explanation 👍 Hopefully we'll get a more thorough documentation and some more examples from Immutable.js |
+1 for the solutions described here! |
+1 |
+1 solutions posts.valueSeq().map(post =>
<PostComponent post={post} key={post.get('id')} />
) |
+1 thanks |
If you don't want to lose the key-value relationship you can also use
|
When using I settled on using this syntax in the end. posts.entrySeq().map( ([key, value]) =>
<Post key={key} value={value} />
) |
* Bump rupture to 0.6.2. * Bump gulp-sourcemaps to 2.0.1. * app/alt.js: Add support for https://github.com/goatslacker/alt-devtool. * app/routes.js: One-line import. * Load "Space Mono" 400 from Google Fonts. * app/api/index.js: Remove obsolete import. * Remove the last remaining image – favicon should suffice to demonstrate how to handle static assets. * Add .post-footer className. * Remove Brooklyn United address in footer. * Remove mastheadColor from AppStore. * Fix indention in various files. * app/components/Header/index.js: Tidy consts. * Various: Move defaultProps, propTypes into class (thanks to es7.classProperties). * app/components/Posts/index.js: Fix "Using Maps as children is not yet fully supported. It is an experimental feature that might be removed. Convert it to a sequence / iterable of keyed ReactElements instead." warning; @see immutable-js/immutable-js#667 (comment) * Fix NoteBox avatar size for retina displays, touch styles along the way, add "reblogged from blogname" to "reblog" notes. * setInnerHTML for PostQuote .source. * Close navigation when clicking a react-router <Link> in it. * Simplify navigation CSS.
You could instead of passing Immutable Collections such as Maps and Lists to your React components, pass normal js objects and arrays, respectively. Thay way, it's easier to read and understand, and you remove dependency/boilerplate of Immutable from your React components. Remember that Immutable Map each keys and values method return an iterator, which can be converted to an array using the spread operator inside brackets. This way, using a normalized state for a Todos demo app e.g: const stateShape = Record({
todos: Map({
1: {
id: 1,
name: 'Eat a lot'
},
2: {
id: 2,
name: 'Take span'
},
})
}) I'd suggest a mapStateToProps function like this: [...] // some other code
const getProjectsArray = state => {
const todos = state.get('todos')
const todosArray = [...todos.values()]
return todosArray
}
const mapStateToProps = (state) => {
projects: getProjectsArray(state)
}
[...] // Some other code Notes: |
Wouldn't that, however, kill any performance optimization done on react components based on ImmutableJS? |
@Ciul that's going to cause unnecessary rerenders every time your state changes because you're generating a new object every time, unless you implement shouldComponentUpdate with a deep comparison, which can be costly depending on your object. |
|
@wSLecHayfIeNdock That behavior of The immutable v4 version of your snippet: posts.map((post) => <PostComponent post={post} key={post.get('id')} />).valueSeq().toArray(); |
@andrewcapodieci That's why I suggest using Reselect. This will make a kind of cache and will return same array if not changed. |
@Ciul are your transforming your immutable objects toJS() in selectors or using .get() syntax in jsx? |
I have a strange request here. I'm also using Typescript, and converting to using However what is the type that should be set for the component that receives a Seq? It shouldn't be an Immutable Seq. It should be some sort of "Functor" type that supports Furthermore, this is basically React rendering of a Map. Does converting to an entrySeq mean that every time, the Map changes, we have to reproduce a list so that React can render it. It seems rather inefficient for React, and it seems that it would be better if there was some key-value structure that was also always iterable without needing to be converted into a different in-memory representation. I want to use some generic functor type instead of immutable Seq so to avoid the dependency of react components on immutablejs. To clarify what I'm asking: Some examples: m = new Map()
// this doesn't work because React doesn't know how to render the Map type
jsx= <ul>{m.map(v => <li>{v}</li>)}</ul>
// this works
jsx = <ul>{m.entrySeq().map([k, v] => <li key={k}>{v}</li>)}</ul>
// this works, but why bother converting to an array needlessly incurring another O(n) operation
jsx = <ul>{m.entrySeq().toArray().map((v, k) => <li key={k}>{v}</li>)}</ul> Assuming that the JSX expression does an O(n) operation Questions:
|
Try reduce()
|
Avoid mapping Immutable.Map as React children. Co-authored-by: Vladimir Gorej <vladimir.gorej@gmail.com> Ref immutable-js/immutable-js#667
Avoid mapping Immutable.Map as React children. Co-authored-by: Vladimir Gorej <vladimir.gorej@gmail.com> Ref immutable-js/immutable-js#667
Hi,
I'm doing the following inside a render() function on my Component:
Where
posts
is anImmutable.Map
, and each item in itpost
is also a Map.This seems to work but I'm getting the following warning:
Warning: Using Maps as children is not yet fully supported. It is an experimental feature that might be removed. Convert it to a sequence / iterable of keyed ReactElements instead.
What alternative approach is suggested? I don't want to lose
Immutable.Map
's functionality like.hasIn
and.getIn
.Thanks!
The text was updated successfully, but these errors were encountered: