We are migrating our web application from React to SolidJS. We want to make the change gradually by converting pages one at a time.
I have been using astro to run both react and solidjs.
The problem I encountered was navigating between react pages and solidjs pages, as they use different routers (react-router-dom and solid/router).
How can I navigate between these two UI libraries?
React uses virtual DOM and re-renders whole DOM tree with each state update. To reduce the work, it diffs and batches previously rendered branches.
Solid renders components into actual DOM elements and there is diffing or batching but some built-in methods/components keep object references to reduce re-calculations if related state branch is unchanged, i.e mapArray, indexArray, For and Index. It is closer to caching than diffing and batching.
So, mixing and matching at component level will be hard to reason about and certainly will be sub-optimal in terms of performance. I believe the best option is to split the work at the root level and migrate each root level components as a whole.
To make it more concrete, lets say you have three paths in your router:
/home
/contact
/about
So, you will have three root level components:
Home
Contact
About
Migrating each of them one by one will be cleaner and more performant.
However, if your application is complicated or hard to split at root level or if you don't want to maintain multiple routers, then use Solid-js for rendering the root level components, because those will be actual DOM elements, and mount the React components carrying the old logic on top of them. So you will have have multiple ReactDOM.render calls mounting legacy components on the DOM elements initially rendered by solid-router. I think that will be the best course of action.
Related
With SSR, JavaScript must be fetched for interactivity, which is often achieved via hydration. How will this be achieved with server components?
React server components don't have state, event handlers, etc. and cannot themselves be interactive. But they can be interleaved with client components, which can be interactive.
Also - React server components still require Javascript. Even for server components, even though no bundles are sent down, they are still "hydrated" in the sense that they are turned into JSX elements and then rendered onto the page as part of the React tree.
See https://blog.plasmic.app/posts/how-react-server-components-work/ for a complete look:
Why invent a whole new wire format? The goal on the client is to reconstruct the React element tree. It is much easier to accomplish this from this format than from html, where we’d have to parse the HTML to create the React elements. Note that the reconstruction of the React element tree is important, as this allows us to merge subsequent changes to the React tree with minimal commits to the DOM.
I'm building a marketing page and using a Wordpress-like CMS. As a result, most of the page's DOM will be server-side rendered. We have some interactive components on the page which we want to use React to build. Hence each interactive component will be its own React root and initialized with ReactDOM.render().
This is probably fine if I had one/two instances. The problem is I have a few hundred of them. Will this lead to performance issues if I call ReactDOM.render() hundreds of times on the same page? If so, what kind of issues? Startup time, interaction, page load time, etc?
What other downsides to this approach are there?
Some of the research I've done and read:
https://github.com/facebook/react/issues/12700
Is it OK to use React.render() multiple times in the DOM?
We will be doing our first project using React.
It will not be a Single Page App, but a Multiple Page App.
What I'm trying to figure out at the moment is : what's the difference between a component and an app.
If I only use components, can I still use Redux to have some state management on the current page ? Or do I need an app for this ?
Thanks for the information you can bring !
THoma
There is no special object called "React App". React Components build an "React App" by coming together.
But React Components are formed like tree structure. That means each component have a parent component so you can create a React Component that named "App" and can put another components inside it.
You don't need redux for state management in React Components.
I hope the answers have helped.
Your app may contains a single component and still it will be a react App. If you are using multiple components in a page you can still use react-redux. Redux is basically a container for your states and let suppose you need some state from one component to be consumed in another, Redux provide you a mechanism to make the communication efficient and predictable.
You can also look at the React Context APIs as an alternate to Redux.
An app is simply a component that holds the root of the work you are trying to do. For example an App may have the navigation menu, testimonials, adverts, content, login avitar etc.
If you are making a single App per page (For example a testimonial) then you would still have a SPA. For example, adding testimonials, searching, editing.
You should only use Redux if you are using a SPA with lots of different parts with data in common. If you are making a one-app-per-page and there is no cross over in data then you can simply using Reacts State/Props to hold your data.
Redux is good, but it forces you into a complex path your should try to avoid. If you find yourself wanting data from different domains (customers address and a list of testimonials) then you should use Redux.
If this is a new applications (green) then I strongly recommend you build the whole thing within a SPA using React-Router to control components. you can use frameworks like Next.JS to ensure the site remains small in size (dynamically loading script only when required).
I have a reagent single page application. At the root component, I have a route dispatcher that renders component according to route. Something like:
(defn page []
[(get component-lookup #current-page-name)])
I have a list page and a detail page, where user frequently switches back and forth.
Problem is, switching between these two pages destroys and re-create an entire page worth of components. This slows down page transition noticeably, especially in mobile devices. In contrast, switching from one detail page to another is very fast, as react figured only a few components need to be re-rendered.
My first attempt at optimization is to have both pages rendered all the time, but add display:none whenever they are not visible. This speeds up page transition, but changes the meaning of lifecycle methods. For example, component-did-mount would execute, but the component is not visible and I cannot update its scroll position.
Would there be a better way to do this? Maybe it is possible to unmount a component tree, save it along with its subcomponents and states/virtual dom, to be remounted later with new props?
I don't think you're going to be able to do this without forking react. The lifecycles are inherently tied to modifications to the virtual dom--that's their whole point of existence.
It's a little surprising that the mere rendering of the DOM elements are too slow, unless your page has thousands of dom elements or lots of media. What are you doing during mount? If it is compute intensive, I'd look there to see if you can separate out that logic and cache it so that it is a lightweight process to switch components.
React relies on the data-react-checksum attribute for reusing markup, which is only set in renderComponentToString (used for server-side rendering of components).
How can I reuse the react-component markup when the component is rendered client-side only?
Background
I'm working on a client-side only webapp. One of the project's goals is to render as quickly as possible, reducing UI "lag" from uninitialized elements, JS loading/parsing, and so forth.
I'm want to cache the rendered react-components markup using localStorage so the previous UI state can be restored as early as possible (again for performance reasons without waiting ~200ms for react to be loaded and parsed).
Strictly speaking, there's no way to turn a string of markup into a live React component (at least not in a performant way). Plus, it doesn't really make sense as your component might have had hidden state that aren't shown on the final rendered DOM string. If you try to revert the string into a component, it'll lead to state inconsistencies.
Something neat to do is to serialize your data into localStorage, and then reproduce your components from that data. But this more or less helps in your case.
But still, you can roll your own small logic on putting the string markup, then letting React destroy it subsequently by rendering a second time.