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.
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
Is it possible to reference existing HTML element in React?
I have a page where React used only for small part of components and I have "video" element that exists on page before React loads. Then I have a react component which have a couple of props that should affect video element.
What is the best/correct way to achieve this?
Currently, in render method of a component, I use document.getElementById('video-' + this.props.videoId) and then manipulating it. I thought that I can somehow use "refs" to say to reuse the existing HTML element, but not sure how and didn't found useful information.
Thanks!
What I understand is, you have an app, probably built in some other stack and you are trying to use React inside that app. The page is loaded before and then the React component renders. As pointed out by Icepickel, refs are for the components that are created by you inside the React app. So, you can't use that here.
Normally, it is discouraged to directly access the elements in the DOM. But since you are using it on a part of it, so it is totally fine. But doing it in the render() method is not the right choice here.
Instead what you can do is, utilize the React lifecycle methods to control the video player in a better way. Normally when a component is mounted on the DOM. Following lifecycle methods are called in the following order:
constructor
componentWillMount
render
componentDidMount
So, what I will suggest is, inside the constructor set the state using document.getElementById('video-' + this.props.videoId). [I am assuming the page laods before the react component].
let el = document.getElementById('video-' + this.props.videoId);
this.state = {
videoPlayer: el;
}
And then later when your component is mounted. Inside the componentDidMount, change whatever you want to change in the video player.
I have also created a small Code Sandbox Sample to elaborate on the lifecycle methods. This way, you will be able to write cleaner code and easily manage the state of the video player.
I have multiple view in my application, I need helpl in how to use reusable component effectively ? Is it ohk if I create viewspecific component from reusable component ? - Generic Tree View . For users View which will render with user specific data and actions .
I have written re useable component in my react app.Which I have to use it with different data and action is it ohk to creat new component which use resuable component and provide data related to that ?
i.e
Component - DepartmentTree which renders and some functions related to Department. So finaly I will render
Component - usersTree same way here it calls and methods related to users . In the users view I will render
It's definitely OK to create a view-specific component that renders a reusable component. You could let this depend on how big your page is. If it includes a lot of components, then do split them up in view specific components.
About the data, you have a few options... First of all you could map the data response to a general structure that your TreeView component can read, so you only need to pass some props to the TreeView component. You could do this in the redux reducer.
If you require specific data different behaviour, but you still want to use the reusable TreeView component, you could think about creating a Higher Order Component. This component will wrap your reusable component and add some specific logic to it. You can read about it and see some good examples here: https://reactjs.org/docs/higher-order-components.html
The most important thing I always keep in mind: It's not always about how you finally do it, it's about keeping it simple, understandable and consistent.
I know It may sound like a dumb question, But I am not able to get this solved in my head. Please bear with me.
In case when we use a state management system in React like Redux / Mob X, I guess the main purpose of these state management techniques is to provide a single source of Data and a more structured approach of updating it.
Say, I am Using a state management library(MobX) for React, And suppose I have a parent component which makes an http API call and updates the MobX store with the API response. Now I need that data in one of child/nested components.
My Question is, Should I pass that data as a prop to child component or should I enable child component to connect with Central Store and directly get that data ?
by connecting the child to store, I am turning the Child into a class component, which is making it more heavy and React optimisations may not apply. I am defeating the whole purpose of a functional component.
Awaiting replies.
Best Regards,
Lalit
This completely depends on the situation. I would suggest splitting your components up in 2 parts:
Components that could be re-used in other projects
(Higher level) Components that are so specific to this project that they probably never will be re-used.
For components of category 1, I would suggest not using mobx store directly, but instead make pure react components. (eg think of a dropdown, or an ajax dropdown component).
For second part components (think of, header, footer, section components specific for your website). just make them directly interact with the Mobx store, so that you can way quicker code what you need (instead of constantly having to prop everything).
addition
For components of category 1 you can always wrap them with the #inject() method. This way for example you could turn a dropdown component into a UserDropdown component that uses the mobx store for its state. (The inject method injects mobx state as props in the component).
const UserDropDownComponent = mobx.inject(stores => ({users: stores.userStore.users}))(DropDownComponent);
// usage:
<UserDropDownComponent />
Warning
For pure components wont always see changes of mobx state. To Fix this you need to wrap the component in an #observe annotation. Or you have to inject the props by wrapping it into: mobx.toJS(yourMobxStateProperty)
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,