Animate parts of child components in React - javascript

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.

Related

Animating layout of list items when new items added to top of a list in Framer Motion (React)

I have a list of items and I'm adding additional items to the top of this list with a button.
I want the items already in the lift to smoothly animate down to accomodate the new items.
I'm using AnimateSharedLayout and I have it working fine if it's a simple list with no custom components as can be seen in this sandbox.
However, I would like to use a custom component as the item added to the list. As can be seen in this example, this breaks the smooth layout transition.
I've tried multiple solutions of this, including converting my custom component to a motion component using motion(Item) but I can't get the desired behaviour to work.
It seems like this functionality should be possible. What am I doing wrong?
Many thanks, Ben.
I've realised that this was an issue with me declaring my Item component inside my App component. After moving it outside the main App component all works as expected.

How to breakdown components in a multi page ReactJs application?

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.

Render one React component inside other

I am new to react & I am using material-ui and I want to design a custom autocomplete in React where once data is selected from dropdown it appears as a chip in the text input. I am using the onNewRequest property of material-ui autocomplete but I am not sure how to render a chip component inside it.
Can someone guide me how to do it properly? I want to design recipients like layout found in gmail. I know there are npm packages available but I need to design it purely from material-ui so please guide with a proper approach
Thanks
The question is very broad but I'll try to at least point you in the right direction.
You don't need to render the chips inside the autocomplete, create a a new reusable component. The parent component will contain both the autocomplete and the chips. This will contain all the state. It has two child components:
The first child is always going to be the autocomplete, modify the material-ui styles to make it transparent and without an underline/borders. Whenever an element is selected, send an event to the parent to add the element to the chips array in the parent state.
The second child is the array of chips. This is only a presentational component, receives an array of chips, and the chips might contain another prop event to remove the chip.

Proper React-ful way to handle a function in a parent component that will only act on selected child components?

So to simplify it to an extent, I have two React components, one that's a child of the other. Lets say they're ItemTable and ItemRow. ItemTable has many ItemRows. ItemTable gets invoked and receives an array of items. For each item in this array, an ItemRow gets created inside ItemTable. I want to be able to select certain ItemRows, each one tied to one item, and perform one specific action on each selected item at the ItemTable level. I have a checkbox on each row for selection, and a button in ItemTable to start performing the action on each selected item. There are two ways I can think of doing this, and I'm not sure which would be the 'proper' way of doing it in React.
Option 1: Have an empty array initialized at the ItemTable state. Each time a checkbox in ItemRow gets checked, it calls a handle function passed down from the parent ItemTable state that either adds or removes it from ItemTables array. In other words, the list of items to act on is being kept track of at the ItemTable level, and then when the button to process the actions is clicked, it parses the array and performs the action on each item.
Option 2: Have a variable initialized to false at the LicenseRow level upon creation. When checked, it changes the LicenseRow's state to true. When unchecked, false. When the button at the LicenseTable level is checked, it goes to each child, and if it's marked as true (checked), process that item.
I'm going back on forth on which I think would be the better way to do it. I know React is a top-down data flow, and so I'm leaning towards option 2, but I feel like managing the list of children should be the job of the parent. I'm not sure if either way is necessarily 'wrong', but in your opinion, what's the better way to process these items?
Both strategies are valid and there is no right or wrong answers here. In my experience, Option 1 is the more common approach to take.
It has a few other benefits over the Option 2 as well:
Generally I find it easier to set up and debug (I believe you need to use a ref to access anything on the child).
On larger collections, it will perform better as it already knows which items are selected before processing. Option 2 would have to enumerate the entire collection, even if only one item was actually selected.
Having the parent own the state enables you to do more with it more easily. For example, you can disable the button if no items are selected for processing.
I know React is a top-down data flow, and so I'm leaning towards option 2
In my opinion the data is still only flowing down in Option 1. The parent make the decision about what data to change when the callback is fired and passes it down to the children.
In the end the choice is yours, so good luck. :)

Simple React.js implementation

I have a relatively simple app with a header and a main section of content. The main section can show up to 4 different types of components, but only 1 component at a time. Each component needs to have the ability to transition (slide) from one component to the next depending on the state.
As of now my main application component holds the state as to which component should be shown. This main application component also renders all 4 of the top level components. Each of the 4 top level components hide/show themselves based upon the application state. Is this the best way of toggling the different components on and off, or should I manually mount and unmount each component? If I take the mount/unmount approach am I still able to easily transition each element?
I would have upvoted or commented on Douglas' answer but I dont have enough rep!
ReactCSSTransitionGroup will do what you want. Adopt the tutorial example to suit your purposes and dont forget to write your animation styles first (ReactCSSTransitionGroup relys on CSS animationend callback to know when the elements have left/entered the dom). It will add helper classes for you so you can create a transition effect between the (incoming and outgoing) elements.
A ReactCSSTransitionGroup will probably do what you need, at the very least you could look at the implementation to see how they do it.

Categories

Resources