Every React component has something called props
A component’s props is an object.
It holds information about that component.
To see a component’s props object, you use the expression this.props.
You can pass information that becomes part of the props, in fact it
becomes a property within props (eg this.props.yourProperty).
For Example,
by adding the desired property (firstName)
to the ReactDom.render for the class
it will attach it as a props.property. Eg...
ReactDOM.render(
<Greeting firstName='Gary' />,
document.getElementById('app')
);
Then, inside the CLASS called Greeting, you will be able to refer to the
property with a this.props.firstName call.
Now the class (Greeting) will have access to the property firstName. Eg...
class Greeting extends React.Component {
render() {
return <h1>
Hi there, {this.props.firstName}
</h1>
}
}
this. - refers to the class object (Greeting) itself.
this.props - refers to the props object inside the class.
this.props.firstName='Gary' - refers to the property itself.
...and because we need to include the value of the property inside the <h1></h1>
element we need to put it inside curly braces { }.
import React from 'react'; import ReactDOM from 'react-dom'; class Greeting extends React.Component { render() { return <h1> Hi there, {this.props.firstName} </h1> } } ReactDOM.render( <Greeting firstName='Gary' />, document.getElementById('app') );When passed to the .html file the result would be
Let's say you wanted to pass the .props from one class/file to another.
(from (class Greetings) in Greetings.js TO (class App) in App.js)
And also NOT having a ReactDOM.render() being set-up in the Greetings.js file
as it will be in the App.js file now.
Greetings.js
import React from 'react'; export class Greeting extends React.Component { render() { return ( <h1>Hi there, {this.props.name}!</h1>; ) } }In order to be able to pass the class Greeting you need to export the class so it can be imported by the App.js file.
App.js
import React from 'react'; import ReactDOM from 'react-dom'; import { Greeting } from './Greeting'; class App extends React.Component { render() { return ( <div> <h1> Welcome to The App.js file! </h1> <Greeting name="Gary" /> </div> ); } } ReactDOM.render( <App />, document.getElementById('app') );
We have to import the Greeting class
at the top of App.js in order to be able to use the Greeting class.
When calling the Greeting class we are adding the props (property) we want
(name="Gary" ), which will get read in
the Greetings.js file and dealt with there (this.props.name).
The App.js file will be the one that performs the main ReactDOM.render() as this
is the controlling file.
If you need to add some logic that changes the output of the
Greeting class then that logic should go AFTER the
render in the class (NOT inside the RETURN), eg...
Greetings.js
import React from 'react'; export class Greeting extends React.Component { render() { if (this.props.name === "Gary") { return ( <h1>Hi there, {this.props.name}!</h1>; ) } else { return ( <h1> Hey, you're not Gary are you, {this.props.name}! </h1>; ) } } }
You define an event handler as a method on the component class, just like the render method.
If you are to pass methods from one file (.js) to another then the method(s)
MUST be part of the class, eg...
class Example extends React.Component { myMethod() { alert(`I am an event handler. If you see this message, then I have been called.`); } render() { return ( <h1 onClick={this.myMethod}> Hello world </h1> ); } }
There you will see the method...myMethod() {}
created after the class declaration.
NOTE
There is NO COMMA after the myMethod() {} and
before the render is declared.
myMethod() {} is being set as the
onClick event handler for the <h1> element in
the class using .this, eg...
onClick={this.myMethod}
the curly braces {} are required as it is a variable/method being passed...
AND the method does not require the () when passed.
So NOT onClick={this.myMethod()}
But IT IS onClick={this.myMethod}
This is because we only want the method to run when the onClick is fired.
At the moment we are just telling the system the name of the method
we want to use and saying that we do not want it run just yet.
The same principle applies when passing the event handler method between .js files
You would pass it as a property, so using the
Greeting.js
App.js
files from above, you could add the Event Handler you want to use
Let's say I want to be able to click on <h1>
So I would add the onClick attribute to a <h1> in Greetings.js...
return
<h1 onClick={this.props.myPropsMethod}>
Hi there, {this.props.firstName}
</h1>
Then the App.js file would need to change so it includes the method
(myMethod) when passing information to Greetings.js...
import React from 'react';
export class Greeting extends React.Component {
render() {
return <h1 onClick={this.props.myPropsMethod}>
Hi there, {this.props.firstName}
</h1>
}
}
App.js
import React from 'react'; import ReactDOM from 'react-dom'; import { Greeting } from './Greeting'; class App extends React.Component { myMethod() { alert(`I am an event handler. If you see this message, then I have been called.`); } render() { return ( <div> <h1> Welcome to The App.js file! </h1> <Greeting firstName="Gary" myPropsMethod={this.myMethod}/> </div> ); } } ReactDOM.render( <App />, document.getElementById('app') );
Welcome to the App.js file!
Hi there, Gary
You would then be able to click on
Hi there, Gary
and then you will get an alert message saying...
I am an event handler.
If you see this message,
then I have been called.
Although you can name your EVENT HANDLERS whatever you want
it is common practice to :-
If you are naming an event that is to be an onClick event then you should consider
calling it something like
myMethodClick
myMethodHover for an onHover event
myMethodKeyPress for an onKeyPress event
etc...
Sometimes a property that you pass to other classes may not have a value
It is possible to set default values by giving your component class a property
named defaultProps and setting each required property a default value, eg...
class CatComponent extends React.Component { constructor(props) {} render() { return ( <div> {this.props.catName} the Cat <br /> EyeColor: {this.props.eyeColor }, Age: {this.props.age} </div> } } CatComponent.defaultProps = { catName: "Sandy", eyeColor: "deepblue", age: "120" }
So, if you run it with...
ReactDOM.render(
<CatComponent />,
document.getElementById('app')
);
The above is passing NO property values, you would get...
Sandy the Cat
EyeColor: deepblue, Age: 120
BUT if you ran...
ReactDOM.render(
<CatComponent catName='Tiddles' Age='7' />,
document.getElementById('app')
);
The above is passing ONLY the catName and age property values, you would get...
Tiddles the Cat
EyeColor: deepblue, Age: 7