Why does react empty attributes when using a web component? - reactjs

I am pretty new to react and trying to use a web component in the template and there are is a thing i dont understand.
It can be seen in this example below if you run the page (may need to hit reload once). Then watch the console. You will see the log in the constructor() the outerHTML is not "ready" yet its missing all attributes in the markup and they arrive only later on (in the connectedCallback) which is the second log.
https://stackblitz.com/edit/react-ts-jcjuvs?file=App.tsx,index.tsx
Whats happening here? Is there anyway to force the attributes to be available initially? Or not taken off and then put back on?
Note that doing this in a normal page does not have the same effect.
https://stackblitz.com/edit/js-l4uh4f?file=index.js,index.html
a) whats happening?
b) can i make this not happen?
Thanks!

There no no guarantee that a web component will have access to attributes in the constructor and attribute values can change at anytime. You should use the attributeChangedCallback lifecycle callback to know when values are set.
The element's attributes and children must not be inspected, as in the non-upgrade case none will be present, and relying on upgrades makes the element less usable.
Requirements for custom element constructors and reactions

Related

How React Virtual Dom is faster? At the end of all its going to hit call browser API to update the real DOM

I read through all the articles in internet. Still i cant understand and mind is puzzling me questions again and again that is
At the end of all the virtual DOM it is going to call the browser API to update the real DOM then how come it will be faster?
Is virtual DOM of React have special access to browsers core API's to modify?
I cant understand? Any resolves this questions Thanks in advance
Here is a talk given circa 2013 (v0.4.0) by the two guys behind React. They describe exactly how it works. Unlike data binding and dirty checking (Angular, etc.) React uses one render method that's called recursively. It then generates a long string that is a representation of the DOM. The concept is actually really simple.
https://www.youtube.com/watch?v=XxVg_s8xAms
Yes, you are right finally the task is to update real dom but the virtual dom comes in picture before updating the real dom. how ?
Suppose you want to update any/many element(s) in Dom tree element then there should be a mechanism to find which element(s) needs to be updated in real dom i.e the browser screen we see.
So this dom finding algorithm executed in virtual dom i.e a javascript copy of real dom(a html dom tree).
React creates two virtual dom, one from existing real dom and other from the changes made. These two virtual dom comparison saves time. The difference of this comparison used for updating real dom.
At the end of all the virtual DOM it is going to call the browser API to update the real DOM then how come it will be faster?
Any speed benefits come from minimizing the number of DOM manipulations that are needed and doing them all at once. The virtual DOM is react's way of calculating the minimum set of changes.
Here's what i mean by calculating the minimum set of changes: The page starts off looking one way, and then you want to make it look some other way. To get there, you're going to need to make one or more changes to the DOM, but there are many different ways you could do it.
A really bad way to update the page would be to wipe the entire document, and then rebuild every single element from scratch. Most likely though, you can reuse most of the page and just make a few updates to select parts of the page: add a div here; update a property there, add an event listener there. That's what you want: a small number of steps that take the old page and turn it into the new page.

React nested Component, arbitrary communication

There are many answers regarding react component communication, but seems none of them resolved my problem. Here is my problem's detail. Please help! Thanks in advance.
I'm building a flexible form. The UI is generated by nesting components.
The form data structure could also be nested json objects.
i.e form can have some inputs and sections, sections can have some inputs or sections, and go on.
sections is just UI layout components, doesn't care about data or state.
But input (could be text input, checkbox etc anything to capture data)
The problem I'm facing is any input's validation could depends on any other inputs' value.
i.e inputA has validation expression like formData.inputB >formData.inputA + formData.inputC
But they could also have no dependency at all if you don't give a validation expression.
If I pass the whole formData down the component tree, every time I type in one input, the whole form will rerender.
I have considered redux, but real not sure how redux can help such case. I'm still relative new to react and redux, so I could be wrong.
So what could be a viable solution?
Its a common issue when you're modularizing form elements. I have the same problem.
Redux is by far the most controlled solution. All of the components can listen and update the same object simultaneously. But you can also attach functions as props from the parent that you bind to the parent. The function would fetch the state of the parent and update the state like a makeshift store. If you're a good developer, this is possible but neither are simple to do. Good time to learn :)
There are various solutions to your problem, but in general it shouldn't even be a problem, because rendering (even of large forms) should be quite effective with React.
The core tool for adjusting performance in React is the shouldComponentUpdate method of your component classes. If you're smart about what you pass to the individual form fields and then implement shouldComponentUpdate properly on them, you should be able to update only when needed. In your particular example, you don't need to pass the full object everywhere.
You can just pass value, onChange and isInvalid to each field and calculate the validity at the root (where you have access to the full state). Then the shouldComponentUpdate of your fields can decide just based on those props. (Obviously this is a simplistic example, but as a principle it's sound.)
Sure, Redux is another possible solution. If you keep the state in Redux store and only connect each of your fields to the portion of the state it needs, you should be all set. It brings quite a change in architecture though, so you should choose Redux only if you really want it for your app as a whole.

What exactly the purpose of React Virtual DOM

While going through react I came up with the following doubts:
DOM operations are very expensive
But eventually react also does the DOM manipulation. We cannot generate a view with Virtual DOM.
Collapsing the entire DOM and building it affects the user experience.
I never did that, Mostly what I do is changing the required child node(Instead of collapsing entire parent) or appending HTML code generated by JS.
Examples:
As a user scrolls down we append posts to parent element, even react
also have to do it in same way. No one collapse entire dom for that.
When a user comment on a post we append a div(comment element(HTML code)) to that particular post comment list. I think no one collapse entire post(dom) for that
3) "diffing" algorithm to check changes:
Why we need a algorithm to check changes.
Example:
If I have a 100 posts, whenever a user clicks on edit button of a particular post, i do it as follows
$(".postEdit").click(function(){
var post_id = $(this).data("postid");
//do some Ajax and DOM manipulation to that particular post.
})
I am telling the DOM to change particular element, then how does diffing help?
Am I thinking in a wrong way? If so, please then correct me.
You are correct that people don't tend to collapse and recreate the entire DOM when they need to update a single element. Instead, the best practice is to just rebuild the element you need. But what if a user takes an action that actually impacts lots of elements? Like it they star a post or something, you want to reflect that on the post and maybe in a stars count elsewhere on the page. As applications get complex enough changing all of the parts of a page that need to be changed becomes really complicated and error prone. Another developer might not be aware that there is a "stars count" elsewhere on the page and would forget to update it.
What if you could just rebuild the entire DOM? If you wrote your render methods and stored your state such that at any point, you could with certainty render the entire page from scratch? That removes a lot of these pain points, but obviously you lose all the performance gains you got from manually altering parts of the DOM by hand.
React and the virtual dom give you the best of both worlds. You get that optimized DOM updating, but as a developer you don't have to keep a mental model of the entire application and remember what you need to change for any given user or network input. The virtual dom will also potentially implement these changes more effectively than you by literally only rebuilding the elements you need. At some point you might be rebuilding more than you should "just in case".
Hope this sort of makes sense!
This discussion can be very helpful to understand Virtual DOM and it's implementation in different UI frameworks.
Why is React's concept of Virtual DOM said to be more performant than dirty model checking?
There are couple of other links as well which explains it in better way.
https://auth0.com/blog/face-off-virtual-dom-vs-incremental-dom-vs-glimmer/
http://teropa.info/blog/2015/03/02/change-and-its-detection-in-javascript-frameworks.html

Inserting text into input in descendant component with React

I'm diving into react for the first time but I'm having some difficulty with a particular requirement. I have the following component structure:
Survey
--QuickTextOptions
----QuickTextOption
--Question
----Answer
------TextAnswer
As you probably can tell, I'm working on a survey application. A survey author would create a question, then answers (i.e. sub questions or options). There will be a number of different answer types including checkbox and text.
Also at the top of the survey, above the questions, are a list of "quick text" options. When one of these is selected, some text is appended to the value field of the appropriate TextAnswer's input field. A user can select as many of these as they'd like.
This is trivial to do with just javascript, but I can't figure out a good way to do this with React without adding refs to components down the chain of the survey.
If I pass it in as a prop, have AnswerText as a controlled component, and set value={this.state.value + this.props.quickText}. It just re-inserts the text on the handleChange event of AnswerText.
I'm considering using refs and calling child functions from parents but refs seem to be discouraged and I'll have to do this for Question, Answer, and AnswerText in order to pass it down the chain which seems a bit too much.
Is there any other way to fire an event to a descendant down the chain with some data? It's a one time addition so props seem to not work well for this.
Do you use something like FLUX and global state? In my practice, usually you build such app working around global state which stores your input data. This way you can edit it transparently from different places according to action events (the only ones which can modify that input value, inputs themselves are not doing that).
So I see that it should look like this:
You pass references to global state object deep into your components and to your form's input.
When you start typing each new character triggers event to modify global state value for this input. You're getting updated value instantly in your component's props and component renders newly entered character.
When you want to modify input from some other component (by pressing button) you do almost the same. You click on button and it triggers event saying that global state value for that input should have "some string" added. Your input component receives callback with new props and renders this text instantly.
By saying event I mean special event which gets some value and inserts it into global state. Rest is done by framework.
Hope this will help you to design your app. The approach I described above is a short description of how Tictail Talk web chat client works now.

Preferred way of creating links with backbone.js

I'm trying to wrap my head around backbone.js but I'm finding it hard due to the lack of (IMO) good examples.
First of all, what is the best way of getting a link to an object.
If I want to get the edit url of an Album model I could do album.url() + '/edit', is this really the best way?
Also, I'm trying to make my application work 100% without javascript so I don't want my URLs/links to say /albums/#1/edit, I want it to be /albums/1/edit and override this in JS.
I'm thinking I create normal URLs and use jQuery.live to call router.navigate in backbone.js
I never got this to work however, when I call router.navigate('/albums/2', true) the URL changes but my show action is never called. If I refresh it's called so the route is matched.
What am I missing?
The basic answer, which is kind of frustrating, is "there is no preferred way!". Backbone.js doesn't tell you how to set up links, you can do it any way you like. I found this flexibility just as annoying as you do, at least at first.
So here's the way I'm approaching this on my current project, with the (big) caveat that this is just one of many ways to do things in Backbone:
For the most part, I don't use actual links. There's no explicit reason not to, but it means you have to keep track of a bunch of URL strings that have to be consistent. I would rather stick all the URL formatting in my routers and not deal with it elsewhere.
To open a new "top-level" view, like an editing screen, I set something that fires an event. In the application I'm currently working on, I have a global State model, and to open a new view I call state.set({ topview: MyTopView }). This causes the state object to trigger change:topview.
Any piece of the UI that needs to change when the top-level view changes has an update method bound to change:topview. When the event fires, they look at state.get('topview') and update as necessary.
I treat my routers as only marginally specialized parts of the UI - they're essentially views that render in the browser address bar, rather than the window. Like other views, they update the state object on UI events (i.e. a new URL), and like other views, they listen to the state object for changes that cause them to update. The logic that the editing screen has the URL albums/<albumid>/edit is fully encapsulated in the router, and I don't refer to it anywhere else.
This works well for me, but it adds an entirely new pattern, the global State object, to the Backbone structure, so I can hardly call this the "preferred" approach.
Update: Also note that .url(), in the Backbone idiom, refers to the model's URL in the back-end API, not the front-end URL (it's not like Django's get_absolute_url). There is no method in the default Backbone setup that gives you a user-facing URL for your model - you'd have to write this yourself.
Also, I'm trying to make my application work 100% without javascript; so I don't want my URLs/links to say /albums/#1/edit, I want it to be /albums/1/edit and override this in JS.
you can do exactly this w/ pushState. just enable it in your Backbone.history.start call:
Backbone.history.start({pushState: true})
this tells Backbone to use the HTML5 History API (a.k.a. "PushState"), which uses full URLs exactly like you're wanting.
read up on the history api here: http://diveintohtml5.ep.io/history.html
and I wrote up a 2 part series on using pushstate w/ the second part focusing on progressive enhancement in backbone, to do what you're needing:
http://lostechies.com/derickbailey/2011/09/26/seo-and-accessibility-with-html5-pushstate-part-1-introducing-pushstate/
and
http://lostechies.com/derickbailey/2011/09/26/seo-and-accessibility-with-html5-pushstate-part-2-progressive-enhancement-with-backbone-js/
hope that helps :)

Resources