Altering the content of a react component manually - reactjs

I ended up in a quite awkward situation where I have to manually alter a React component before it get's rendered.
I'm using draft.js and have created a CompositeDecorator.
The decorator returns a react object that is styled just the way I want, but I need to replace the text of that component before I render it.
I can see that the object has a props property, that has a text property inside it. This is the text I want to change, but that property is readonly.
I can't do it the normal react way, since I don't control the part of the application that actually creates this component.
Are there any way to change this property, or to create a copy of this component that is an exact copy except for the text property?

Related

always lift up states of react child components?

My react-materialUI app has multiple dialogs, and some of these dialogs are containing the same mui data grid (a list of projects).
Example: a save project dialog. This dialog contains this mui data grid and a mui text field, both as child components.
By clicking on a row in the data grid, I want to set the content of the text field to the value of the selected row.
To accomplish this, I could lift up the value state of the text field and the selectedRow state of the data grid to the save dialog.
somehow I find it hard to understand that a supposedly reusable component isn’t handling their state by itself.
Is lifting states up really the best practice or is there something basic I overlooked?
If some behavior in the data grid should affect the value of the text field, you probably need to lift the state for that text value.
But you might not need to lift the state for the data grid. Instead, you could pass an onSelect prop which you use to set the text value, something like:
<DataGrid onSelect={(project) => setText(project.name)} />
Further reading
The beta React docs have great content on such topics, e.g. https://beta.reactjs.org/learn/thinking-in-react#step-4-identify-where-your-state-should-live

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

Hook re-render whole page on single change in a sub component

I create 2 Text Boxes one with hook and the another one with the old style, now in Hook mode when the user input change the textbox value the whole page rendered, but with old style there only the text-box rendered not the whole page, if you have the complex page with many objects like (Data Table, form, buttons, inputs, etc..) the single change on one of these components forced to re-render everything and it decease performance, for example typing in the text-box take time to effect on page and the delay time is more than user typing speed.
the one workaround solution is using the callbacks and useMem but if the page is complex(lots of objects as described, and all of these objects has many properties the callback and useMem is very very complicated to handle single object property.
SandBox Example
This is exactly how react hooks should work. what will cause a rerender in react? two things:
change in props
change in hooks or say in a better way hooks state
in the second case, the useInput state is changing so that causes a rerender and it's absolutely normal behavior. I think using custom hook in that way is not a good practice.
I recommend reading this article for more information on react rendering: https://www.codebeast.dev/usestate-vs-useref-re-render-or-not/

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.

Sharing state between all instances of same component?

I have a Tooltip component that when hovered displays a simple tooltip.
When you mouseLeave the component, a setTimeout fires, and when it ends, the tooltip is closed (setState({ open: false })).
Now I'd like to add a behavior to reflect the one of the native OS tooltips:
When you mouseLeave a tooltip, but instantly mouseEnter a different tooltip, the previous tooltip is instantly closed, and the new one gets opened.
To do so, I need to have a shared state between all the instances of Tooltip component. I could use Redux but it seems a bit overkill for a so simple task (I'd need a container that interacts with the store and makes an action and a property available).
Are there simpler solutions?
The best way to share information between ReactComponent is the Flux architecture. Redux is one of them.
A more simple option is to use the browser native storage used to store temporary information : it is similar to global variable but with particular scope and duration definitions.
Move the shared state into the state of the parent component of all Tooltips, have this parent define a method setWhatever to set the value, and pass this method to Tooltip components via a property. This way, children can call their setWhatever property, which is really the one of their parent, when they need to change the state.

Resources