Accessing React component displayName in HTML - javascript

How can I access a rendered React component's displayName property in HTML? There seems to be some way to do it given React DevTools, but I've been reading through the source code for that package and can't figure out how they're doing it. I recognize that this might be cross-referenced from the associated JS file, but I'm hopeful that's not the case.
Context: I have a script that identifies certain components in the prod version of our app and adds a red border around them, which works fine. In React DevTools I can see the displayNames of those components even on prod (they're not minified for whatever reason, which is beyond my scope of curiosity right now). I'd love to be able to surface those displayNames in addition to the added border.

Related

Visual builder to work with manually hard-coded templates/components

I wonder, is it possible to create a visual no-code builder to work with JS components (e.g. React JSX) if them are manually hard-coded before?
Let me explain what I mean.
Suppose a simple React component pages/index.js previously written by a developer manually:
function HomePage() {
return <div>Welcome to Next.js!</div>
}
export default HomePage
How can we change such a component in the front-end using a visual builder?
For example, we want to add a new HTML element (e.g. H1) inside the existing div.
As I can understand, the builder first needs to know in which JS file the HTML markup is stored to update it. So we can add id="homepage" to the div first and then store a relation as a config like
{"homepage": "pages/index.js"}
And now if we add a new element inside <div id="homepage">, the builder adds the element to the DOM of the div at the client, then takes the whole updated DOM of the div and writes back to the file index.js according to the config
Ok, but the file contains not only HTML markup - it's JS (React) code.
How to keep all the JS code e.g. function HomePage(), return, export default and so on ?
As an option, we can separately load all the JS code as HTML including non-HTML code as #text nodes. Then update the DOM and re-write everything back to the file.
But it sounds complicated and may cause unexpected issues.
So what solution would be the best?
Or maybe there is a ready React-specific solution?
Or maybe it's a bad idea at all to parse and re-write manually hard-coded components by visual builder and the only solution is to store everything as JSON like "homepage":{"div", {"class":""}, "Welcome..."} which is more easy for re-writing ? (but requires a new render)
It depends
I believe the answer that you are looking for very much depends on the level of flexibility that you want your no-code builder to have.
Depending on that, your project could benefit of the trade-offs and advantages of different solutions.
Let's briefly remember that basically a React component will need some props that then will be taken through a render template and output a working HTML. This is assuming a basic case where you don't need your react components to be smarter. Additionally, JSX is just sugar coating over function calls, so you could basically just compose functions to output a React component independently of using the JSX syntax. Hence no need to declare HTML, just changing the output of your no-code tool to JS instead of HTML.
For example, if you can modify how the no-code tool render, you can specify that when moving an element inside another you basically:
Highly Flexible & Customisable
In a highly flexible setup, I will recommend going through the last option you numbered, having a Data-Driven UI is the most common of the cases for complex systems. For example, Figma has an option to export the designs as react components, you can read how they do it here. Basically they take the tag output from figma which is a JSON of tags and create some React componets using templates. If you define "you own UI language" you could have quite a good control over what blocks you can build and define the way of interacting with them (e.g. adding a img component could be quite easy if you know the props and what it needs to render, then creating a React template for it is easy).
Limitations: you require to plan quite well the API of the parser and interaction between different sets of items.
Simple no-code builder
For simpler scenarios you could go with the first approach that you mention, you won't even need to add ids, some tools like React Developer Tools can already inspect the VirtualDOM to understand which part of the render belongs to which React Element (using react internals, which could take some time to understand, but for example you can inspect in the rendered how they use the data-reactid for identification). Knowing this, you can already define the template functions for the render() method (so the JSX output), and separate it code wise, so that when you generate the code, the HTML template is split from the React code as much as possible.
Silly example of how it could look:
// htmlBlockTemplate.js
export const helloPageTemplate = (props) =>
`<div> <h1>${props.title}</h1> </div>` // This can be generated from the `no-code`
// page.jsx
export const Page = (props) => {
return helloPageTemplate(props)
}
Using functions it could look like:
const Page = (props) =>
return React.createElement('div', null,
React.createElement('h1', title: prop.title, `The title ${title}`)
);
}
Limitations: eventho you could, adding custom components (like another React Component or a web component), it becomes more difficult since you will also have to deal with the import graph and probably.
Inevitably you will need to tweak how the render of the component works (rather by creating a parser from your UI language, or changing how the react component is written. If you have a good control of AST, then writing a parser for either of the cases should not be a problem.

Why does my D3 code break when I set the script type to module?

I am working on a project built with Javascrpt, jQuery, and Vite.js. My colleague built a data visualization using D3 - a US states map - that I need to implement in the project on a specific page. They built the component using test data, my job is basically to load the component onto a page passing it actual returned data from an API call.
Everything in the test project works perfectly, but when I tried to implement this code into a script file in the project - literally copying and pasting from the working version - I got an error saying certain properties could not be read. After failing to debug for sometime, I randomly tried removing type="module" from the script tag link in HTML, and boom, everything worked. Does anyone have an idea of why this would be? I cannot get this code to run when the script type is set to module, except I need the script type to be set to module since I'm importing lots of components for other aspects of the page.
With the way the CodePen is set up, I couldn't replicate the issue since the HTML and JS files are automatically linked. But if you copy this code into your editor, and then in the html, set the the JS file to a module ` You'll see the issue.
Thanks. I'm at a total loss for what to do here. I could put all the D3 code in it's own script file, but then I have no way pass it variables from other files if it's not a module.
Per the comments, the following lines in my original code were not working in strict mode:
this.uStates = uStates;
this.uStatePaths = uStatePaths;
The fix was simple, I just needed to write the following instead:
window.uStates = uStates;
window.uStatePaths = uStatePaths;

How to get react component Name inside componentDidCatch in producation build?

I used error boundary inside (componentDidCatch)I want to log which react component is break in producation build.
conclusion is get react component Name inside componentDidCatch in producation build.
I read many article and below link this is same as I asked in question but it's not solve my problem.
Getting React Component by name
and I also saw some webpack related things (production config's uglify) but it's not proper clear.
let me know if any simplest way to solve this issue
By design, you should never be able to see debugging information in a production build. What you are trying to accomplish here is an anti-pattern. However, if you still want to go through with it, you can use:
this._reactInternalFiber.elementType.name
Note that it might be instable due to using a private property that belongs to React.

Render react component in bundle.js only when a certain page is loaded

I recently started using webpack in my ASP.Net project, and I just wanted to add a new react component as well now.
The following problem just came up for me. I did import my react component in the index file and it gets packed with webpack without any problems.
However, I am loading the bundle.js which webpack outputs in a shared page.
The problem I am facing is the following now:
In the file which contains my react component declaration, let's call it Post.jsx, I am calling ReactDOM.render(<PostFeed />, document.getElementById('postFeed'));. Now, as stated, the bundle.js is being loaded on a shared view, so every page initially calls the render function at some point. However, the element 'postFeed' which the component is being rendered inside, is only available when the user navigates to a specific page.
What options do I now have in order to only render my component when I navigated on a certain page? Can I somehow reliably determine this from javascript? I would really like to keep the comfort webpack provides, but I know when there is no other choice I could also split my Post.jsx file and add it as a script in the html code for the specific in which the component does find its element.
Any advice?

Reactjs server-side rendering seems to not change a thing on the client side

I'm trying to optimize my big ReactJS project and I've stumbled upon a conclusion, that React code in the browser is not taking any advantage of server rendering. I'm sure that server-side rendering is working properly, I can see data in the page source returned from server, with all the data-reactids.
Setup: server-side code is rendered in Node. React version 15.0.1. I'm using ClojureScript and rum, but it shouldn't matter in the end
Test environment: Using React.addons.Perf, wrapping it around initial mount on the client side.
Test 1: proper server-side rendering
Total time around 1.8s, Inclusive Time of root component about 1.5s. React.addons.Perf.printWasted() shows nothing.
But what is the most puzzling part for me is that React.addons.Perf.printOperations() shows one operation: "set innerHTML" with the whole app's html (e.g. <div data-reactroot=\"\" data-reactid=\"1\"><div id=\"wrapper\"...). Like the whole server-side rendering result was discarded and this client-rendered HTML is inserted in the DOM, probably causing re-rendeding.
Test 2: invalid checksum; by purpose I've added some extra attribute on the server-side only.
Of course the "React attempted to reuse markup in a container but the checksum was invalid." warning appears.
However, everything else is similar to the Test1 above! Similar times, and also the single "set innerHTML" operation. This confirms for me that even if checksum is correct, React ignores pre-rendered markup (because it seems to do the same operations in the similar times whether checksum is correct or not)
Test 3: turned off server-side rendering; returning empty mount-point container.
Times about 0.2s longer. The only real difference now is that there are many operations, most of them update attribute or update styles and one set innerHTML with {"node":"<not serializable>","children":[],"html":null,"text":null}.
Question/Problem
I don't know what to think about it. React advertises SSR as a way to speed up application bootstrap, as it does not need to generate DOM tree again (or rather: insert it in the document; it still need to be rendered in order to compare checksums, right?). But for me it seems like nothing is gained.
Can someone who is successfully utilizing SSR tell me what are his/her reading in printWasted() and printOperations()? The only thing I managed to find was this audit: https://github.com/reddit/reddit-mobile/issues/247#issuecomment-118398416 (only printWasted, though) - none of my tests shows any entires in printWasted.
Well, it all was simple: after upgrading to React 15.4.2 Test 1 shows no operations, as I expected it to in the first place. So in the end it all was issue of (not so) old library version. Yet the times of mount are still very similar.

Categories

Resources