React component not displaying if dynamically generated list items empty - javascript

I have a react component that contains a child list of components created using a map:
var listItems = model.arrayItems.map(function(item) {
return(<ChildComponent item={item}></ChildComponent>)
}, this);
And the component's render function then adds this list of child components:
return (
<div>
<h1>My items:<h1>
<ul>{listItems}</ul>
</div>
);
The problem is that the react component is not showing up in my browser when listItems is empty. However, if I resize the browser window, the component does show up. Does anyone have any advice on what might be causing this behavior?

So it did turn out to be an issue with ChildComponent. In fact, it seems to have been a CSS issue.
ChildComponent itself had a nested set of dynamically generated list items. These grandchild components had the CSS property for width set to 100%. Changing this property to "auto" fixed the issue.
My understanding is that when transitioning to a state in which the top-level list is empty, and given the way React is managing unmounted components, the grandchild component's CSS style of 100% (of parent element) somehow confuses the browser's rendering because its parent component is no longer mounted. If anyone knows the cause of this behavior in more depth, it would be great to hear a deeper explanation of this.

Related

What is the benefit of creating an extra div container when using React Portals?

I'm trying to understand React Portals, so I looked to the documentation.
I still don't understand why in their examples (https://codepen.io/gaearon/pen/yzMaBd and https://reactjs.org/docs/portals.html#event-bubbling-through-portals) they are creating an extra div in the constructor and passing it to the second argument of the createPortal function.
Why don't they use directly the modalRoot container like this ?
const modalRoot = document.getElementById('modal-root');
class Modal extends React.Component {
render() {
return ReactDOM.createPortal(
this.props.children,
modalRoot,
);
}
}
In the codepen example, the explanation is given by this comment
Create a div that we'll render the modal into. Because each Modal component has its own element, we can render multiple modal components into the modal container.
In this stackblitz example, I tried to render multiple components into the portal container without using an extra div and it seems to work perfectly, React.createPortal already appends the child to container, and when the component is unmount, it only removes the child from the container and doesn't clear all the container's content, so we don't have to do this manually. Am I missing something ?

EmberJS Component - Run custom function after DOM has fully loaded

I'm struggling to fully grasp the component lifecycle. I've created a component, but I need my custom javascript function to run after the DOM is complete. I've scoured through the EmberJS Docs and Stackoverflow, but any documentation I come across doesn't work as I intended.
My Issue
I've attempted to use didInsertElement and didRender, but they still get called before my repeating elements have loaded in the DOM. How do I circumvent this to have my Javascript run after the DOM has fully rendered.
My Attempts
Below is an extremely stripped down and barebones example using an alert in place of my script. The desired outcome is to have this alert appear after the DOM is rendered, the below examples have it alert before.
import Component from '#ember/component';
export default Component.extend({
didRender() {
alert('didRender');
},
didInsertElement() {
alert('didInsertElement');
}
});
Thanks in advance.
Assuming you have the following template
{{#each this.items as |item|}}
<ItemComponent #item={{item}} />
{{/each}}
You want to know when the the list is done rendering?
extract the above template into a component.
<ItemList #items={{this.items}} />
where ItemList is defined as
import Component from '#ember/component';
export default class ItemList extends {
didInsertElement() {
console.log('list was inserted');
}
}
Here is the code:
https://canary.ember-twiddle.com/6e023f1413fbce6bab8954f3eec73554?openFiles=templates.components.item-list.hbs%2Ctemplates.components.item-component.hbs
If you open the console, you'll see:
item 1 was inserted
item 2 was inserted
item 3 was inserted
item 4 was inserted
item 5 was inserted
list was inserted
Although creating a child component is always safe, ( as said in ember's docs
When a view has children, didInsertElement will be called on the child view(s) first and on itself afterwards.
)
, however, even without child components, the didInsertElement hook will trigger only after the component is inserted to DOM. Here is an example twiddle.

How to keep the value of a variable current throughout multiple React Native components

I have a Parent React Native component which is composed of three children components, Header, Body, and Footer. This is how it is arranged inside a file MyScreen.js:
<Container> // I am using NativeBase Container
<Header />
<Body />
<Footer />
</Container>
Definitions of these three children components are contained in separate files, e.g. Body.component.js, and so on.
I want to access an array data structure Foo contained in a different file FooArray.js, and it is imported by both Body and Footer components. Foo is manipulated inside the Body component (I push() objects to this array here) and its length Foo.length is displayed in the Footer component.
How can I make sure that whenever a new object is pushed to Foo in the Body component, its new length is immediately reflected in the separate Footer component?
Any ideas, regarding not only the expected solution but also optimal re-structuring of the project files if needed, are appreciated.
React solves this problem with state.
You import your data (foo) into a top level component (Container) and assign it to the state. Then you can pass the state down to children components as props.
All the children components can use these props and will automatically update if the prop changes.
If you want to make changes to the state from within the children components, you should pass handler functions (defined in the parent component) to the children components as props.

What is the preferred way to show/hide components in React.js?

What is the preferred way to toggle (show/hide) a component in React? To my knowledge, there are two ways to do this.
Solution 1:
Conditionally rendering the child component inside the render() method of the parent component.
{
this.state.showUserModal ?
<UsereModal onClose={this.onModalClose} user={this.state.selectedUser}/>
: null
}
Solution 2:
Using a property at the child component which inside its own render() method returns null or the children based on the boolean.
<UsereModal show={this.state.showUserModal} onClose={this.onModalClose} user={this.state.selectedUser}/>
The second solution causes to initialize the component only once (the constructor is called once) and the first solutions do not. I am having issues with this because in need to initialize my state based on the props inside the constructor, so I am forced to use solution 2. But what are the most React way to handle this?
In both cases if the parent state or props are changed both the parent and the child components will be re-rendered. Hence there is no performance gain of the second solution. But if the child component should not be shown in the second case it will be mounted and rendered (but not shown). Taking it into account I would suggest to use the first case.
If you want to persist the DOM elements in the UI, you should go using style binding or class binding:
<UsereModal style={{display: this.state.showUserModal ? 'block' : 'none'}} />
I think the first solution is better since you do not need to initiate UsereModal component with its own state that will control should component be shown or not. I prefer also jsx notation for conditional rendering
{
this.state.showUserModal && <UsereModal onClose={this.onModalClose} user=
{this.state.selectedUser}/>
}

Unmount React Parent without Unmounting Child

Is it possible for a React component's parent to be unmounted without the child being unmounted? What work arounds exist to achieve this result? Surely there must be some (potentially hacky) way to do this.
Example
When this:
<Parent>
<Child/>
</Parent>
changes to this:
<Child/>
I would like Parent's lifecycle method componentWillUnmount to be called without Child's lifecycle method componentWillUnmount being called.
I recognize this may not be possible but was wondering if anyone had a creative solution to this problem.
Update
Here's my specific use case (hopefully I do a good enough job explaining this):
I have a higher order component which doesn't introduce any new dom elements but essentially just introduces some new context for the child component. The child component renders slightly differently depending on whether or not this context is present. Unfortunately when I remove and add the parent a new instance of the child is created and it unmounts/remounts. The only issue with this unmounting and remounting is that the child element does some dom measurements to decide whether or not to show a horizontal scroll bar and overflow menu for some of it's elements. When it unmounts/remounts there is an unsightly flash of this menu.
You could handle the rendering logic. For example inside your render function:
if (showParent) {
return (
<Parent>
<Child/>
</Parent>);
} else{
return <Child/>;
}
Then whenever the boolean showParent changes the component renders differently.
The super-parent object, calling this render() , should store the state in order to update them and preserve the child (and parent, in case you want to switch it back on).
Therefore it should also contain the state of the child, in order for it to be kept. In other words: move the model hierarchically up to the super parent.

Categories

Resources