I need to get a child component position in a tree in my React app to make a 'tour/guide' for my application. if it was vanilla js, I was able to easily get the target node using document.querySelector() but since in react we have to use refs to get access to the element, and it's not a good way to use refForward in many child components to approach the target one from the grand parent component, what is the best solution to get properties of a child component in a tree?
I think one possible solution is saving target elements' position in a global state manager like context or redux, but since the position is changing frequently, it would cause some critical performance issues in the app.
Thank you in advance.
Related
I have a state varible for color in a canvas file
const [selectedColor, setSelectedColor] = useState('#FFFFFF');
and I want to access it from a sidebar to put a colour picker in it. Is there a way I can set the variable from another file and have it update on the screen like a normal state variable? Thanks.
There are a number of possible solutions and I would say that it depends on your component tree (i.e. how is your application structured).
If your Sidebar and Canvas component have a shared parent component (i.e. a component that has Sidebar and Canvas as its children) then the easiest way would probably be to use a concept called lifting state up whereby you move the state logic to that shared parent component that passes state down to its children via props. Read more about lifting state up in the official React documentation.
An alternative approach is to work with React Context, which is already built-in in the library. This requires more set-up so I would suggest starting with lifting state-up if possible. Read more about Context here.
There are also other solutions such as working with state management libraries (e.g. Redux, Jotai,...) but they are too complicated for this simple use case.
Given all efforts to make React work fast, I am still having performance issues when it comes to DOM manipulations governed by React. Is there a way to switch to direct DOM manipulations from under React without breaking it?
PS: I am specifically interested in removing DOM nodes.
A safe way to handle this is to build your performance-sensitive component entirely outside of React.
This can be done via web components. React has a page that explains how web components and React components can be used together over here.
Thus, you can have complete control over the shadow DOM within your web component to do whatever DOM manipulations you wish to do, and then you can insert your web compoment within React without any worry of React's virtual DOM algorithm messing with what you've done in the shadow DOM.
React is all about manipulating the state to trigger re-renders of the DOM. Instead of arbitrarily removing the element from the DOM as you would in jQuery, you should update the state by filtering out the item from props. items that will trigger a rerender of the DOM with the item removed.
For better manipulations you can use state for small and redux for midium to big projects.
useRef and useState are easy to use and manipulate.
I understand that you should not manually manipulate the DOM nodes rendered by a Vue component for reasons including:
After another render, Vue can override any changes you did
It can interfere with Vue's patching algorithm
My use case is I would like to implement a way to move a DOM node to a separately-controlled location for the purpose of displaying it fullscreen. Imagine an editor widget with a fullscreen button that "pops out" the editor and overlays it fullscreen.
I understand that I can achieve this with CSS alone using fixed positioning, but I'm not interested in that, I'm particularly interested in the consequences of moving the DOM node out from wherever it is and appending it directly to the <body> element. Will Vue still be able to patch the nodes correctly after the parent component re-renders?
I have experimented with this already and I have a working implementation, and I haven't encountered any issues yet. Still, this doesn't ease my concern, and the Vue docs don't talk about doing something like this.
What potential issues, if any, might I encounter?
portal-vue is unsuitable because it recreates the component instance each time it is relocated, which I do not want.
Depending on how the component lifecycle works in Vue, moving a component in the DOM might trigger lifecycle methods. E.g. with Custom Elements, moving means triggering disconnectedCallback of the component, and subsequently connectedCallback. This is often where the component initialization takes place.
Rather than moving the component manually from the outside, consider giving the component itself the ability to relocate.
I have a parent component that has state and a child component that uses the youtube-react api to create a video player. The child component contains both state and methods that are used to work on the video player (e.g. event handlers).
I want to ask if should I separate out the child component by making it a stateless functional component? I can do this by placing all the methods and state of the child in the parent component and then pass all relevant methods/data down to the child via props.
My concern with separating the child component is that will make understanding how everything works confusing. Also, it will result in a huge parent component as the parent component already contains methods and state for other child components.
I think it all breaks down to personal preferences. I like to write components which are reusable and handle all the logic by themselves, so that I can use them as often as possible. This could result in some components get bigger then others.
I think a good starting point is here: https://reactjs.org/docs/thinking-in-react.html
I have some data in the rough form of:
Parent->child->grandchild->great grandchild
I have created a component for each level in the tree, with the top component storing the whole tree as state, and passing branches down via props etc to its children.
As the top component manages the state, it is responsible for CRUDing any of the children. If I simply want to add a new great-grandchild, I will have to replace the entire state tree on the parent component. Is this a vastly inefficient approach, or will React work out which components to re-render? Is there a better or more idiomatic way of achieving what I need?
For this React supports "keyed children". This basically means adding a key={someUniqueId} attribute to all your child components.
"When React reconciles the keyed children, it will ensure that any child with key will be reordered (instead of clobbered) or destroyed (instead of reused)."
To answer your question
Is this a vastly inefficient approach?
Yes, if you do not use keyed children for every small change in one of the leafs the whole tree will be rebuild from the root up.