this.props.children vs this.props.someName - reactjs

It seems, I see two equal ways to delegate property via props:
let App = React.createClass({
render(){
return (
<Unit someName="Push me!" />
)
}
});
class Unit extends React.Component{
render(){
return (
<button>
<span className="glyphicon glyphicon-heart"/>
{this.props.someName}
</button>
)
}
};
and
let App = React.createClass({
render(){
return(
<Unit>
<span className="glyphicon glyphicon-heart"></span>
Push me now!
</Unit>
)
}
});
class Unit extends React.Component{
render(){
return (
<button>{this.props.children}</button>
)
}
};
What's the general purpose of props.children?
Can I consider it as equal to props.someName?
Could be provided some examples where props.someName doesn't work but props.childred does?

Maybe I am wrong, but I think that the existence of children is just syntactic sugar to allow an HTML-like nesting of elements. As far as I know, it is exactly the same as any other property. In fact, while using JSX you can add children as an ordinary property and it doesn't make any difference.
let App = React.createClass({
render(){
return(
<Unit children={<span className="glyphicon glyphicon-heart">Push me now!</span>}/>
)
}
});
class Unit extends React.Component{
render(){
return (
<button >{this.props.children}</button>
)
}
};
ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

Generally speaking, this.props.children is used to refer to all the children that are wrapped in a custom component.
<View>
<Text>One</Text>
<Text>Two<Text>
</View>
Here, the two Text elements are children to your View. In the class definition(or equivalent) for your View component, you can refer to all the children components by this.props.children. But I think you already understand this much.
From what I understand, as a rule of thumb, you pass some values/properties, etc as props to a component.
If you want to, for example, render some components in a custom component that you are defining, you need to be able to refer to what components were declared in the implementation code from definition code, so you use this.props.children.
My language is a bit muddled, but I hope this is clear enough.

Related

Mutiple ReactDOM.render functions?

I'm starting to learn react and getting a problem when calling multiple ReactDOM.render functions:
react:
class Header extends React.Component{
render(){
return(
<div>
<p>Test1</p>
</div>
)
}
};
class Main extends React.Component {
render(){
return(
<section>
<p>Test2</p>
</section>
)
}
};
ReactDOM.render(<Main />, document.getElementById('root2'));
ReactDOM.render(<Header />, document.getElementById('root'));
html part:
<body>
<div id="root"></div>
<div id="root2"></div>
</body>
I'm getting the error:
Target container is not a DOM element.
When searching for this problem I got the information that it should be possible to call ReactDom.render multiple times. So I appreciate your help!
Edit: Just tried it with one html tag and changed the id. It seems to have a problem when the id is not "root"...
You are right, you should be able to call render multiple times in your code.
But instead of doing that why don't you do this:
Class App extends Component {
render(){
<React.Fragment>
<Header />
<Main />
</React.Fragment>
}
}
ReactDOM.render(<App />, document.getElementById('root'))
This is easier, correct and performance superior.
I really see no reason as to why soomeone woudld need to put 2 different renderers on one page. Its just putting more strain on the browser for no reason and it will slow down your application.

Difference between <function prop="Hello"> and {function("Hello")}

I am currently learning React and I do not understand when should I use these and when should I not? I have seen tutorials where people just use them seemingly interchangeably. Hence, I would like to know what is the differences between them and when should i or should i not use them.
For example, assuming the "function" named component returns a <div>Hello</div> after the call, I can have the following code.
import {function} from './component';
class X extends React.Component{
render(){
return(
<div>
<function Props1="Hello"/>
</div>
)
}
}
Next,I believe can also have the following code, please correct me if I'm wrong
import {function} from './component';
class X extends React.Component{
render(){
return(
<div>
{function("Hello")}
</div>
)
}
}
So it seems like there are two ways for doing the exact same thing in ReactJS? Are there any reasons I should be using one over the other?
When you render it like <function Props1="Hello"/>, React will create a props object, with the properties and values pairs you passed to it.
When you render it like {function("Hello") your props argument will be a string "Hello".
See snippet below:
function App() {
return(
<React.Fragment>
<Component1
props1="hello"
/>
{Component2("hello")}
</React.Fragment>
);
}
function Component1(props) {
return(
<React.Fragment>
Component1
<div>Props: {JSON.stringify(props)}</div>
<br/>
</React.Fragment>
);
}
function Component2(props) {
return(
<React.Fragment>
Component2
<div>Props: {JSON.stringify(props)}</div>
</React.Fragment>
);
}
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"/>
The difference is that first case it is stateful component, so the props has to be passed by something like in your case
Props1=""
then in your function component which in this case is stateful ,you get access to props via this.props.Props1
in second case it is functional component so you can get access to it like for example:
class X extends React.Component{
render(){
return(
<div>
{function("Hello")}
</div>
)
}
}
function function(myprop) {
return <div>{myprop}</div>
}

Exposing function of a React component

Is there a way to expose a function of a React component?
class MyComponent extends Component {
someFunction() {
// I'd like to expose this function
}
render() {
return(
<div>Hello World</div>
);
}
}
In the above example, I'd like to expose someFunction() so that I can call it from the parent component.
In other words, I'm trying to call a function of a sub-component from the parent component.
Two questions:
Can I do this? If so, how?
This may be a more important question: Should I be doing this? I'm always mindful that something I may need now may be exposing an architectural flaw. So, I want to know if I should even be calling a sub-component's function from the parent component.
While it is possible to call a function on a child component, I don't think it would be idiomatic.
If you want to change the way a component renders, you should alter its props and trigger a re-render.
Keeping the interface for a component exclusively through the props helps to better encapsulate the inner workings of the component.
For your specific example, I would rather have a visible toggle that you alter and let the datePicker component decide for itself what it wants to do with that property value.
Can I do this?
Yes, We can achieve that by using ref, assign ref to MyComponent when rendering inside parent component then use that ref to call the function.
How?
Check this snippet:
class Parent extends React.Component {
_callChildComponent(){
this.child.someFunction();
}
render() {
return(
<div>
<div onClick={() => this._callChildComponent()}>Call</div>
<MyComponent ref={el => this.child = el}/>
</div>
);
}
}
class MyComponent extends React.Component {
someFunction() {
console.log('hello');
}
render() {
return(
<div>Hello World</div>
);
}
}
ReactDOM.render(<Parent/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app'/>
But i will suggest you to pass a function from parent component to child component and use that function to pass data or for any other purpose instead of using ref.

how to get element by component name in ReactJS

I'm trying to get the listing of a component in the DOM. Something like
document.getElementsByTagName("ComponentName") but with a component name.
React Components aren't part of the DOM Model. As such, you cannot get a list of Components from the document object.
What you can do instead is to give the React Components you're interested in finding, a certain css class name, which you then can find in the DOM.
For example:
class MyComponent extends React.Component {
render(){
return (
<div className="myComponent">{this.props.children}</div>
);
}
}
class MyApp extends React.Component {
render(){
return (
<div>
<MyComponent>foo</MyComponent>
<MyComponent>bar</MyComponent>
</div>
);
}
}
ReactDOM.render(<MyApp />, document.getElementById("myApp"));
/* get components from their class name: */
var list = document.getElementsByClassName("myComponent");
for (var item of list) {
console.log(item)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="myApp"></div>
You can of course also use id and use document.getElementById() (if the id is unique) or name and use document.getElementsByName(), and other methods. I think class makes most sense.

Change state of parent component from Child component by extending the class

Before marking it as an duplicate read the question completely.
I have two component, say A and B. A extends React.Component and B extends A. Calling super inside the constructor of B will make all the things available under this of A to be available under B also.
The issue I'm facing is, I've a method which will updated the state of A. I'm calling this method from B. This still updates the state of B not A. Is this expected or am I doing anything wrong.
Working example
class A extends React.Component{
constructor(props) {
super(props)
this.updatedState = this.updatedState.bind(this) //bound to this parent
this.state = {
text: 'Hello from the other side!'
}
}
updatedState(){
this.setState({
text: 'I must have called a thousand times!'
})
}
render(){
return <h1>{this.state.text}</h1>
}
}
class B extends A{
constructor(){
super()
}
render(){
return <div>
<h1>{this.state.text}</h1>
<button onClick={this.updatedState}>Update state</button>
</div>
}
}
ReactDOM.render(
<div>
<A/>
<B/>
</div>,
document.getElementById('app')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
Another Example
This is not using the constructor or the super. I instantiate A using new and call the methods. The method is being called but the render is not triggered.
class A extends React.Component{
constructor(props) {
super(props)
this.updatedState = this.updatedState.bind(this) //bound to this parent
this.state = {
text: 'Hello from the other side!'
}
}
updatedState(){
console.log('called')
this.setState({
text: 'I must have called a thousand times!'
})
}
render(){
return <h1>{this.state.text}</h1>
}
}
class B extends A{
render(){
var parent = new A()
return <div>
<h1>{this.state.text}</h1>
<button onClick={parent.updatedState}>Update state</button>
</div>
}
}
ReactDOM.render(
<div>
<A/>
<B/>
</div>,
document.getElementById('app')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
Your second example does not work as it supposed to.
class B extends A{
render(){
var parent = new A()
return <div>
<h1>{this.state.text}</h1>
<button onClick={parent.updatedState}>Update state</button>
</div>
}
}
In the above there is a B object which extends A.
Assuming that this instance of B references adress 0x001 in memory.
var parent =new A() creates an A object and it references another address in memory for example 0x002. This reference is kept in memory which is reserved for instance of object B extends A. that's it. they have just Has - a realationship. But B extends A (B is A ) so they have is-a relationship.
http://www.w3resource.com/java-tutorial/inheritance-composition-relationship.php
Extending B with A doesn't link any new instance of B with a new instance of A. Furthermore, try composition instead of inheritance. There is no specific use case in inheritance that composition doesn't cover. Composition is more natural, more easier to reason, behavior is more explicit and also a lot safer.
Here's how I would do it with composition. I don't know what exactly your use case is, so pardon me if the following refactored example doesn't fit in with what you're trying to accomplish. But nevertheless, you should be able to achieve the same with composition instead of having to use inheritance.
class A extends React.Component {
render () {
return <h1>{this.props.displayText}</h1>
}
}
class B extends React.Component {
state = {
displayText: 'Hello from the other side!'
}
updateState () {
let displayText = 'I must have called a thousand times!';
this.setState({
displayText: displayText
}, () => this.props.onUpdateClick(displayText));
}
render () {
return <div>
<h1>{this.state.displayText}</h1>
<button onClick={this.updateState.bind(this)}>Update state</button>
</div>
}
}
class C extends React.Component {
state = {
displayTextA: 'Hello from the other side!'
}
changeA (value) {
this.setState({
displayTextA: value
});
}
render () {
return (
<div>
<A displayText={this.state.displayTextA} />
<B onUpdateClick={this.changeA.bind(this)} />
</div>
)
}
}
ReactDOM.render(
<div>
<C/>
</div>,
document.getElementById('app')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
Here are a few posts that you might find helpful:-
Composition vs Inheritance
Mixins Are Dead. Long Live Composition

Resources