React has a concept called 'props'. This is how we pass arguments to our components. Props look a lot like HTML attributes.
const Cat = (props) => <p>Meow my name is: {props.name}</p>
// ^^^^^ ^^^^^^^^^^
props
is the parameter of your Component.
const Geoff = () => <Cat name={'Geoff'} />
// Renders <p>Meow my name is: Geoff</p> on the screen
In this case we're calling our Cat
function with a single prop: name
with a value of 'Geoff'
.
<Cat name={'Geoff'} />
is like saying: Cat({name: 'Geoff'})
Both would return <p>Meow my name is: Geoff</p>
Examples:
<Stars stars={5} color="yellow" /> // the stars prop is a number, the color prop is a string.
<Fruit fruit={{name: 'Banana', color: 'yellow'}} /> // fruit prop is an object
<Languages languages={['Javascript', 'Elixir', 'Python']} /> // languages props is an array
React's props make components very reusable.
const Cat = (props) => <p>Meow my name is: {props.name}</p>
<div>
<Cat name="Kipper" />
<Cat name='Sardine' />
<Cat name={"Haddock"} />
</div>
// Renders:
// <div>
// <p>Meow my name is: Kipper</p>
// <p>Meow my name is: Sardine</p>
// <p>Meow my name is: Haddock</p>
// </div>
React also allows you to make components using the class syntax
class Cat extends Component {
render() {
return <p>{this.props.name}</p> //<- This bit is the same
}
}
The props are now in this.props
rather than just props
.
This can still be used by saying: <Cat name={'Geoff'} />
Using classes is slightly more complicated.
The advantages are:
this.state
and this.setState
React components can be rendered on the screen for some time. React will make sure that your components stay up to date on the screen as changes happen.
If the props change react will rerun your function and the result will be immediately displayed on the screen.
For example:
() => <Cat name={'Geoff'} />
-> () => <Cat name={'Dave'} />
You'll initially see <p>Geoff</p>
then you'll see <p>Dave</p>
React takes care of this for you automatically.
You can't make props change without using state.
this.state
- similarly to propsthis.setState({newStateGoes: 'here'})
class Cat extends Component {
constructor() {
super() // <- This is just always needed
this.state = {name: 'Geoff'} // Set the initial state
}
render() {
return (
<div>
<button onClick={() => this.setState({name: 'Dave'})}>Press Me</button>
<p>{this.state.name}</p> //<- We're accessing state here.
</div>
)
}
}
This component can be used like: <Cat />
It will render:
<div>
<button onClick={() => this.setState({name: 'Dave'})}>Press Me</button>
<p>Geoff</p>
</div>
When you press the button this.setState({name: 'Dave'})
gets called. State will be updated to be {name: 'dave'}
. React will automatically rerender your component as:
<div>
<button onClick={() => this.setState({name: 'Dave'})}>Press Me</button>
<p>Dave</p>
</div>
You can use this same technique to change props.
const Cat = (props) => <p>Meow my name is: {props.name}</p>
class CatPicker extends Component {
constructor() {
super() // <- This is just always needed
this.state = {name: 'Geoff'} // Set the initial state
}
render() {
return (
<div>
<button onClick={() => this.setState({name: 'Dave'})}>Press Me</button>
<Cat name={this.state.name} /> //<- We're passing some state as a prop.
</div>
)
}
}
<CatPicker />
initially renders:
<div>
<button onClick={() => this.setState({name: 'Dave'})}>Press Me</button>
<p>Meow my name is: Geoff</p>
</div>
Pressing the button will cause the name=
prop to change. React automatically rerenders the whole thing:
<div>
<button onClick={() => this.setState({name: 'Dave'})}>Press Me</button>
<p>Meow my name is: Dave</p>
</div>