I learned that react uses key to recognise an element (component).
Which of the followings does react consider to recognize an element?
Are there anything else?
key
element type
where the element is located in the entire tree
You are correct in everything you have stated. You can verify it by inspecting your react application's elements and looking at the components. For example, you'll see divs with data-reactroot, data-reactid
You may also want to check out https://github.com/facebook/react-devtools
You're correct in that React uses keys to identify instances (components). And while it's not really about performance, keys are used to determine which instances can be reused (and therefore also leads to better performance). If the keys were to change all the time, React would unnecessarily have to recreate nodes, and child components would lose their state.
Every level of your React application has a key. When using JSX, you can specify the key explicitly using: <Button key={id} />. If no key attribute is provided, React will use the index of the component (in the current level) to implicitly add a key property to the component.
So why wouldn't you always let React do this for you? For components that maintain data in this.state, things can get weird if siblings (in the same level) are removed or re-ordered. You can read more about this in the React documentation.
Related
I see three (3) properties on a value my react component is returning namely keys, props and type and i am blank on how they work. I even see a fourth one called ref when i use the createElement method to create my DOM elements. Any help that would enlighten me on the area will be much appreciated. Thank you.
Just a note - your questions are asking about the fundamental way that React works (pertaining to the use of the Virtual DOM and its component-based structure). I'll try to sum it up as much as possible and give links to resources that might be helpful.
The key attribute relates to the way React uses the Virtual DOM and one of the reasons it works as fast as it does. In short, React supports the key attribute to improve its ability to differentiate sibling elements/components from each other and prevent re-painting the whole element tree if only one of the sibling changes. I suggest reading further on this to better understand it.
The props attribute relates to how React passes data from one component to another (usually from a parent component to a child component). Think of them as the arguments that you pass to a function - where the function is React's internal way of compiling your code and eventually rendering the DOM elements.
type should be pretty straightforward - its used to determine the type of component/element (eg: div, or a React function component)
The ref attribute relates to a way that you can store references to a particular element. By passing a React ref to a component/element's ref attribute, you're essentially storing access to that component/element through the React ref. There are some pretty good explanations out there about how it works on a conceptual level.
Note that my use of the word "component" refers to a React components, and "element" refers to the DOM element
I have found some information online, which is saying that you shouldn't use the index parameter as the key prop when using a map. For example:
{myPersonsState.map( (person, index) => {
return <Person key={index} />
})
According to what I've found, this is not good.
The reason for that, is, whenever you manipulate data in the state (for example, removing the 3rd element in the array), the key for each element, starting from the 3rd position, will definitely change, because each element's key is it's index (which definitely changes), and by that, React will consider the new element's keys as the old ones (before the change).
By that logic, its only logical to think that React will take the new elements starting from the 3rd position, and give them the old keys, which will consider them as the old ones - which will cause React to think it doesn't need to create a new instance of them, and just use the previous elements data to create them.
So, why do I not see that when actually manipulating the state and re-rendering ?
Why does React know that it is a new element on it's own, even though, it has another element's previous key ?
React's key prop gives you the ability to control component instances. Each time React renders your components, it's calling your functions to retrieve the new React elements that it uses to update the DOM. If you return the same element types, it keeps those components/DOM nodes around, even if all* the props changed.
Key prop allows you to return the exact same element type, but force React to unmount the previous instance, and mount a new one. This means that all state that had existed in the component at the time is completely removed and the component is "reinitialized" for all intents and purposes. For components, this means that React will run cleanup on effects (or componentWillUnmount), then it will run state initializers (or the constructor) and effect callbacks (or componentDidMount).
If I am only using React to generate an HTML string in Node (and I am not hydrating the HTML on the client), is setting the key prop 100% pointless?
Keys help React identify which items have changed, are added, or are removed. Since your use-case doesn't deal with any of it, I would say yes it is not required.
In the docs, React says that it doesn't really care for instances as the Components take props as input and outputs elements for you. It gives you an example at the top of how other frameworks have to create an instance and then connect it to the DOM to handle different events. But I don't understand how this is different than what React is doing.
You're not calling new on your component in React, but you still have to render it and create all the same handlers. And this inside the component still refers to the instance, so doesn't React still have to create an instance each time your component is rendered (even if it's a component inside an <li> that's being rendered several times at once).
Traditional frameworks will have to create multiple instances of the same component to connect to each DOM node it corresponds to, isn't that what React is doing too? How else can one component keep track of multiple this's?
Indeed, React creates Component instance internally. You don't need to worry about using new.
React Element is just a plain JavaScript Object that describes what you want to be rendered (React.Component or HTML Element, if type is a String).
From the docs:
An element is not an actual instance. Rather, it is a way to tell
React what you want to see on the screen. You can’t call any methods
on the element. It’s just an immutable description object with two
fields: type: (string | ReactClass) and props: Object1.
The difference is that you the developer are not having to write the code to do all that. You just write the render method and your callbacks and let React worry about creating the DOM elements and the component instances and connecting them together.
I'm just wondering if there's anyway of completely cloning an already rendered React component. I've read about cloneElement but when I render that clone I get an error:
Uncaught error: Invariant Violation: Element type is invalid
I'm also wondering if this will clone the element's child elements, and their subsequent input values. For example, if some text is in one of the inputs, and then the component is cloned, will these values be preserved? Or is my only option to store those values before clone? This will make it very tightly coupled I feel.
As a general rule, we should always try to keep our components as stateless as possible, meaning that the data you input in the form should be stored somewhere outside of the component (a Store, maybe? ... I'm thinking about http://alt.js.org/docs/stores/).
With this approach, you'll have your component listening to that store. You can have as many copies of the component as you'd like, but the single source of truth would be your store.
Another scenario, if the same component should show data from different stores, then do not use stores, and use props. Have the parent component be the one listening to its store, and pass the necessary data to the child component (the one that you want to have clones in several places in your app).
I hope that helps,