I need to know component's width in render method, but getting DOM elements in render method is not possible.
Solving problem I found this article. The problem in article is the same as mine.
Solution:
save component's width to state in componentDidMount method.
subscribe to window resize event and update state.
So I can get component width from component's state.
Anybody knows another approach to solve this problem?
Thanks.
Well, you don't have to save the width in state, you could grab it each time with ReactDOM.findDOMNode(), but this is about the best you're going to get. You can't update in render for two reasons:
your DOM elements are currently being rendered but don't exist yet
Even if they did, triggering an update in render is an easy way to trigger an infinite render loop.
Tldr: Just go with the method you have, that works just fine
Related
Is there any way to create a react component having controllable and/or default-uncontrollable scrolling pos?
I created a react component having overflow=scroll/auto.
Everything is done using ref=elmRef trick and manipulating through useEffect.
Is it able not to use ref anyway? I want to make a purely react way.
I feel using ref is like a jquery way. The manipulation is done after actual dom component rendered, and might trigger the second render at startup if the manipulation causing to modify any states. There is a state that the value depend on the scroll position. Rendering dom twice is wasteful performance.
Here the visualization of the component i created:
We are trying to figure out cause of following issue from styled-components project: https://github.com/styled-components/styled-components/issues/389
There were some changes made to refs + setNativeProps that broke animation in one place, assumingly because some animated related information is not being passed down correctly.
Hence the question to understand how createAnimatedComponent alters initial component, whats added? What could cause animation to break if not passed down correctly?
Please provide ideas / detailed answer if you know what could be causing this issue.
UPDATE
Breaking change related to the issue occurred somewhere within this file for reference innerRef passes down ref, isTag function checks if it is a native component.
animatable components can be animated. View, Text, and Image are already provided, and you can create custom ones with createAnimatedComponent. These special components do the magic of binding the animated values to the properties, and do targeted native updates to avoid the cost of the react render and reconciliation process on every frame. They also handle cleanup on unmount so they are safe by default.
https://facebook.github.io/react-native/docs/animated.html
I have a JSON, and in it there are some fields that I need to calculate.
Where is the best place to do it?
Currently I have set it in:
componentWillMount: function () {
//Iterating over the JSON object
}
All my values are calculated and then the render is called. It works fine. I just wonder am I doing the right thing?
It depends. Are you mounting and umounting that component a lot? Are the calculations heavy?
What you are doing right now is probably fine, as you've said. If you really want to separate the data and calculations from the component you might want to look at redux and reselect
Yes, You can do all your calculations in componentWillMount of your json.
You can then set the state accordingly because setting the state in componentWillMount wont cause a rerender infact your render method will receive the updated state.
So I have an app that has a right sidebar whose visibility is toggled via a button. In that sidebar there can be one of several things [at a time] - chat, help, search. I was looking at some plain HTML from apps which have a similar feature and noticed that they have all nodes rendered, but are just hidden via CSS.
Since I need to do the same thing, I was thinking whether this would be a good idea to do with React. But then I realized that React elements have a state which when updated calls the render method. So I can use the state to store both whether the sidebar is opened, and what is inside the sidebar.
Is that the React way of doing things? Is it better to have all nodes rendered even if they are not visible, or is it better to have the nodes rendered on request via state changes?
My feeling is that only rendering what is visible would be the more standard React way, but in this case, this is mainly a performance decision. If you render everything and just toggle visibility with CSS, the first render will take longer (but the time difference may not be relevant or even noticeable). If you render only the part that's visible, React needs to do a small rerender every time the sidebar content changes. (This may also not be noticeable time.)
My recommendation would be to try both, if you want to test the performance. But I think you won't go too wrong either way.
Suppose we have two sibling react components called OldContainer and NewContainer. There is a child component inside OldContainer that contains a <video> tag, and the video is currently playing.
The user can now drag the child component (with the video) and drop it in the NewContainer, and they expect the video to keep playing while it's being dragged and after being dropped.
So the video appears to stick to the mouse position, and when dragged and dropped in the new container, it animates to its new position (again, it doesn't get paused).
How would you implement this? Can we implement this in a pure way (in line with the spirit of pure functions)?
Clarification: I could have used some other element instead of a video tag for explaining this problem. A NumberEasing element would be a better example, since it would require the props and state of the component to be preserved during and after the interaction.
Update 1: Code examples obviously would be nice, but what I'm mainly looking for is just a general description of how you would approach this problem in a "functional" way. How do you keep your view code simple and easy to reason about? Who handles the drag-and-drop gesture? How do you model the data that's fed into the views?
Take a look at this library : react-reverse-portal
What is it that you want to preserve? Is it Javascript objects that the component holds as state, or is it state in the DOM (like how long a video has played, or text selection in an input box)?
If it's just Javascript objects as state, you're better of moving the source of that state to another service (something like Flux). That way, it doesn't matter if the component gets recreated because it can be recreated with the state that was there before.
EDIT
The way to keep your view code simple and easy to reason about is to not keep state inside your components. Instead, all data that the component needs should be passed into the component as props. That way, the component is "pure" in that it renders the same output given the same props. That also makes the problem of wanting to reuse a component instance a non-issue, since it doesn't matter when the same input gives the same output.
For drag and drop, I'd suggest looking at: https://github.com/gaearon/react-dnd.
How you model the data you pass to view components is up to you and the needs of your application. The components shouldn't care, they should just expect to get data passed as props, and to render them. But the popular approach to dealing with this is of course Flux, and there are many libraries that implements Flux in different ways.
SECOND EDIT
Regarding if you have a subtree with hundreds of components that you want to move: I'd still start off by making the state external (pure components), and render that tree in a new place. That means that React will probably recreate that entire subtree, which is fine. I wouldn't deviate from that path unless the performance of it turned out to be horrible (just guessing that it might be horrible isn't enough).
If the performance turned out to be horrible, I would wrap that entire subtree in a component that caches the actual DOM tree and reuses it (if it gets passed the same props). But you should only do this when absolutely needed, since it goes against what React tries to do for you.
THIRD EDIT
About gestures: I'd start out with listening to gesture events in componentDidMount, and in the event callback call setState on the component with the coordinates it should have. And then render the component in render with the coordinates given. React won't recreate the component when you call setState but it will re-render it (and diff the output). If the only thing you changed was the coordinates, it should render fast enough.
If that turns out to be too slow, like if the subtree of that component is huge and it becomes a bottleneck to recreate the subtree of vDOM, I'd reposition the DOM node directly in a RAF-loop outside of Reacts control. And I'd also put a huge comment on why that was needed, because it might seem wierd for some other developer later.
Create a new variable using const or var. Put the instance of data using rest spread operator, update the necessary data to pass and send the data to the component without mutating the state of component.
Just like:
const data = {
...this.state.child,
new_data : 'abc'
}