Skip to content
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

Merging styles onto children props #1048

Closed
JohnyDays opened this issue Apr 28, 2015 · 13 comments
Closed

Merging styles onto children props #1048

JohnyDays opened this issue Apr 28, 2015 · 13 comments
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@JohnyDays
Copy link
Contributor

(not my actual use case, just a sample of the problem)

Given the view

render(){
  <View>
     {this.mapChildren(this.props.children)}
  </View>
}
mapChildren(children){
  return children.map((child) => {
    var styles = Object.assign(child.props.style, {opacity:0}) // child.props.style contains an int (e.g 34)
    return React.cloneElement(child, {styles})
  })
}

I need to iterate through the children, attributing to each of them the style {opacity:0}, and merging with any existing styles, however the content of child.props.style is an int instead of an object that can be merged.

Given this, my only option is to accept styles through a prop on the parent object, and map them to the children with their keys, this is obviously not a desirable solution. Am I missing something, or is this use case not intended to be supported?
For the record, my use case is a waterfall view, where i need to render the elements and then rearrange them after I know their sizes, but i imagine this applies to more use cases

@brentvatne
Copy link
Collaborator

@JohnyDays - you can get the actual backing stylesheet from the StyleSheetRegistry as @tadeuzagallo demonstrates here

@JohnyDays
Copy link
Contributor Author

Great way to fix my use case thanks!
Just for curiosity's sake, is the original object removed from the props for some performance reason?
Regardless, i'd argue this should be documented somewhere, given I've read most of the docs and still haven't found any reference to it.

@brentvatne
Copy link
Collaborator

@JohnyDays - good point. I believe it is put in the stylesheet registry for perf reasons. If you want to submit a PR with docs that would be awesome! 🚀

@vjeux
Copy link
Contributor

vjeux commented Apr 28, 2015

As a general rule, you don't want to mutate anything, what you want is to make a new object that has the old and new.

In your case you can do

var style = [child.props.style, { opacity: 0 }];
React.cloneElement(child, {style})

@brentvatne
Copy link
Collaborator

👍 to @vjeux's comment, should have pointed that out myself

@vjeux
Copy link
Contributor

vjeux commented Apr 28, 2015

Also, looking up the registry is not going to do what you expect. If the style is an array, then it is going to crash. The proper way to extract information is to use flattenStyle, BUT there are very few reasons to ever use it. Please ask me if you think you need it, there is probably a better way

@JohnyDays
Copy link
Contributor Author

My use case is the following, I am constructing a waterfall view, for which i need to:

  1. Render the children with opacity 0
  2. Wait 1 frame(with requestAnimationFrame)
  3. Grab their sizes using element.measure(), Promise.all helps with coordinating this
  4. Layout the items with position absolute in a waterfall fashion
  5. Apply this layout using css, but I want to preserve whatever styles the person using my component gave to the children

Is there a better way to do that?

On a sidenote, I attempted to use the solution provided in the other thread, but I cannot for the life of me figure out how to import StyleSheetRegistry, I have tried both from the React object and the StyleSheet object, do I have to use the absolute js path?

Edit: My apologies I seem to have missed your first comment @vjeux, I will try it that way. Leaving this for posterity

@vjeux
Copy link
Contributor

vjeux commented Apr 28, 2015

Right now there isn't a better way unfortunately right now. One thing you can do is to do setTimeout(0) instead of requestAnimationFrame in order to avoid skiping an entire frame

@JohnyDays
Copy link
Contributor Author

I tried, the items did not have a width or height upon completing measure().
So I had to switch to requestAnimationFrame

@vjeux
Copy link
Contributor

vjeux commented Apr 28, 2015

Ohh, you are right, nevermind me :(

@JohnyDays
Copy link
Contributor Author

Hey thanks for the help! I have managed to complete the view, I will publish the component to npm once I am satisfied, but incase you were curious, this was how I was able to make it work(still a very small bug to be fixed, but it lays out the views perfectly)

https://gist.github.com/JohnyDays/ab352c6bab57683a2db5

@brentvatne
Copy link
Collaborator

@JohnyDays - nice 😄 looking forward to seeing the module

@x5engine
Copy link

how is @JohnyDays doing?

and @brentvatne cats are smarter than dogs :p

@facebook facebook locked as resolved and limited conversation to collaborators May 29, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 22, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests

5 participants