React app confusion setting state of nested child component - reactjs

I'm an embedded developer who is new to React and am struggling a bit with the behaviour of child components and nested child components.
I understand that for any component to be re-rendered, the state must change. I am using an example of a menu component that has an item component within. When some global level event happens, I want to change the text displayed by the item components.
Here is a fiddle that shows some code that I would expect to work:
https://codesandbox.io/s/dark-rain-8mfsp?file=/src/App.tsx
On clicking the div, the menu's setText function gets called, which calls into the item component, setting the state. This state is used in the render function of the item component, so I would expect both item and menu to be re-rendered.
Instead I get an error saying that I can't set the state of an object that hasn't yet been mounted. I would have thought it had been mounted..
Perhaps the way I have linked the declared components with those in the render functions by calling this.componentname.render() is the issue - but how else could that be done?
Thanks in advance!

Here is a working version of your sandbox.
https://codesandbox.io/s/lucid-bird-qecj0?file=/src/App.tsx:0-899
I see that you are new to react. I would suggest you use hooks instead of class components.

Related

Pass context when render components programmatically

In my REACT application, I'm trying to render a Component programmatically, but pasing to it any REACT context. Let me show you a simple example with this sandbox: https://codesandbox.io/s/kind-carson-u0hup?file=/src/App.tsx
As you can see, what I want to do is rendering <Dialog> programmatically when I click a button. But, inside that <Dialog>, I want to use any context created on the React Tree.
Unfortunately, I am aware that React.render does not pass any context, thus this cannot work: if you click on the button, you will see that, while the context in <InnerComponent> provides the value 'FooBar'. inside <Dialog> I have the default value 'initialValue'.
Thus, the question is, is there any way I can programmatically render a component, AND passing to its any kind of context?
I'm aware that React.createPortal does pass the context, but that method MUST be called inside the return statement of a component, while instead, in my case, I render the <Dialog> after a click on the Button.
Also, yes, I could always have the <Dialog> rendered, and use a prop isVisible.. But this is a simpler example.
I've read several things (some of these in the following links), but none of these really helped me:
https://github.com/facebook/react/issues/17974
Is it possible to pass context into a component instantiated with ReactDOM.render?
Why component rendered with ReactDOM.render loses react-redux context (Provider)
You can not put the render of component outside of your ContextProvider.
Check this link:
https://codesandbox.io/s/busy-curran-pbz6p?file=/src/App.tsx:0-834

React check if component is in focus from a TabView

I have a TabView component that has multiple tabs containing components. These components have entire hierarchies of other components. How could I know from any child component nested arbitrarily deep in one of these hierarchies whether or not it's parent tab is in focus in the TabView?
Preferably, I would want to implement this similar to react-navigation's withNavigationFocus (or an equivalent hook) so that any component can know if it's in tab focus without having to pass props down the chain of components. I'm thinking you could have a TabViewContext that components can register themselves as focus listeners to by doing a useContext. The TabViewContext would be provided by the TabView and the TabView would be responsible for determining what registered listeners are in focus when tabs change. My dilemma is I don't know how the TabView could determine efficiently what nested child components come into focus when the tab changes. Any ideas?
In case the other parent tabs are hidden, you could test for visibility in plain JS, rather than have a much more complex solution...
Checkout this answer on how to do this.
So components that care about the visibility of their parent tab could use a ref for their own DOM elements and test whether they're visible or not. You could build this into a simple helper function or a hook
EDIT:
I'd suggest going with something like this:
Each Tab will provide a context with method for any descendant to register a callback that will be called when the Tab is hidden. The TabView can pass a "isVisible" prop to each tab (if it doesn't already), so Tab can know when its display changes.
When a Tab changes from visible to hidden. All registered callbacks will be called.
I would of course write a hook or a helper function to create this TabVisibilty context so each Tab component can use it in a reusable manner.

React App Prevent Rerender of All Items in Grid When Redux Updates

I've got an app that shows a list of items in a grid. Some of the items have an embedded video which flashes or stops playing (if it's already playing) when it's rerendered.
The list is maintained in Redux. When the user scrolls to the bottom of the page it loads more results which causes the Redux state to update which, in turn, causes the grid to rerender all of the items plus the new items.
I'm looking for a solution that will just add more items to the end of the grid instead of rerendering everything.
I've got a component that holds the entire grid. It renders a component for each item in the grid. In each item I have a component that holds the embedded video.
Any ideas?
If each item in the grid is a component, like you said, you should use React.memo (for functional compoents) or Reat.PureComponent (for class components). It will prevent the component from rerendering if the props have not changed. I can't guarantee your videos will keep playing, but if the only reason they stop playing or flash is because the component is being rerendered then it should fix the problem.
Maybe this can help: when passing information from redux to your component, try to update the list of the objects instead of sending a new one
It's redux UpdateObject method.

React re-rendering resets component's hover state

I set my component to scale 1.2x when hovered over, however, when the component is re-rendered by React while I'm hovering over it, it loses the hover state for a moment and becomes small, then back to 1.2x, (see image). I want it to stay scaled. How can I work around this?
I had this same issue, and it turns out I was declaring a functional component within a different functional component (as a helper component). When the parent state changed, it re-created the internal component, causing the actual DOM to change.
Moving the internal component outside the main functional component fixed the issue.
So this was a problem because I subscribed the whole React render function to the Redux store, causing every action to force a re-render. This was fixed by using react-redux connect instead of subscribing the render function.
Create a flexbox component on the parent of this component and add the onHover function on it.
Try using react-redux's connect which doesn't re-render on every action.
Because , when you use subscribe the render function to the Redux store,
it causes the every action to forcefully re-render.

ReactTransitionGroup code explanation

I'm new to react and I am trying to get my head around the code in ReactTransitionGroup and I am confused as to Why performEnter is called in componentDidUpdate and not componentDidMount. My understanding of componentDidUpdate is that it is called after render and when the state has altered.
So I'm confused as to why it is called here.
performEnter animates the child, and children are animated in and out when they appear in or disappear from the parent component on subsequent renders—they're not animated if they're already contained in the parent upon the first render.

Resources