I have a feature need to implement that is when I'm on the map, I can click in any map position(coordinate) to get the data (data can be many or single) that the position contains. If data is many, it will display a list of items to choose from and see the details, otherwise is a single item.
In case data is many, After I click on the view button to see the item details I want to switch to another position. The weird behavior here is that from the state of details, React didn't render directly to the new position's data, it jumps back to the firstly rendered state then renders the data based on the new position. I want it not rendered back to the list state again, instead renders directly to the new position's data.
How do I achieve that?
Here is the full source code for this sample: https://codesandbox.io/s/crazy-wilbur-rgqrb?file=/src/Map.js
Related
In ReactJs, what would be the best way to breakdown the component hierarchy in a multi-page application ? For an example take an application with two columns. Left most column is the side bar and the right most column is for loading different views.
One view flow would be as follows. Side bar contains a link to view a list of products. Once the link is clicked a set of product with brief descriptions would be loaded into the right hand column.
If the user selects a specific product, the a full detailed view of that product would be loaded in the same panel replacing the original list view.
Now does that full detailed view component comes under the product list component as it's loaded by clicking on a product or is it better to keep it as a child component of the main application ?
You can take a look at 'Thinking in React' link which kind of goes over the same theory on what you are asking which is how do i breakdown my components.
https://reactjs.org/docs/thinking-in-react.html
You should put your data where you have to click/or triggering an event that will make your data change. In this case you would have to click on a link to trigger a product list, then click on the product to trigger product description.
You should not go more than 1 layer deep if you are passing state so don't pass it from parent to child to child. If this is the scenario you should move your state lower.
I hope this gets you going and thinking towards the right path.
I am developing a react JS component with JSX coding structure that gets a JSON array of data from api. The component is a table like structure and has two arrows at the top and bottom. I want to achieve a functionality where on click of top arrow the table rows should be updated with new set of data in rows and vice-versa happens on click of down arrow. Is there a way to achieve this functionality?
It seems you are trying to do some sort of table paging. You can do this by storing the current page on the state of your control, and on the onClick handler:
make the call to the server API to retrieve the data for the next/previous page if you are paging and sorting on the server, then update the state with the retrieved data
or calculate and update the state with whichever rows you want to display if you already have all rows in memory but are showing a small set of them
I've a list (immutable.js) in my store containing multiple objects.
This list is displayed in a component as a table with rows. Those rows are subcomponents displaying one single object. One attribute of those objects should be editable. So onChange() i dispatch an action which should change the attribute of that one specific object. As we should never ever change the state, i return a whole new list with just that single object changed. But because the whole list is a new list object, the table component gets updated every single change. this leads to a really slow working app.
I've just looked at the official todo app example and inspected it with the Perf addon. Realising that they also rerender the whole todos-list on every change (mark as completed, unmark). How am I supposed to fix that?
The biggest factors that will impact your list rendering performance are heavy rendering cycles and expensive DOM mutations. Make sure that your list items are as efficient as possible when they re-render. Done properly, this will make a big difference.
You have a couple of straight forward options.
Break your rows out into their own component (if not already done) and optimize the render and update cycle.
Use a library such as react-virtualized to help with list/table/grid performance.
I'm having a hard time understanding how animate components in React when it involves elements within child components. To set the stage, I have:
A button group component that contains some buttons.
A navigation component that contains some button groups. The navigation component creates arrays of button names and callbacks and then passes them to button group components as props.
Lets say the user takes some action on a page that will change the nav. More specifically, I want to fade out one of the buttons from one of the button groups in the nav.
I'm familiar how to use ReactCSSTransitionGroup and would think to use this in this case, but the tricky part is that the navigation component is the the thing that owns the animation trigger, and the button group component is the thing that owns the button that needs fading. When the navigation component re-renders, it throws away the old button group from the DOM and builds an entirely new one which means the old button group never has the opportunity to fade its button out.
Questions:
Am I using the wrong abstractions here? If I want to fade out the button based on nav state, does the button have to belong to the nav and not in some child component?
When the nav re-renders and new props are given to the button group, why does the button group get trashed and rebuilt rather than the existing one just getting a propsWillChange call?
You're right, it sounds like your child button group components shouldn't need to re-render.
If you're iterating over an array of name/callback pairs to build the buttons, make sure each button is being given a unique key attribute; maybe the name, if that is unique. That will give React a way of identifying which buttons to add or remove and which to leave in place.
With that, your ReactCSSTransitionGroup should work as expected.
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'
}