Morning:
Afternoon:
create-react-app
map
with componentscreate-react-app
map
with ComponentsPerson.js
class Person extends React.Component {
render() {
return (
<li>Hello, {this.props.person.name}!</li>
)
}
}
export default Person
PersonList.js
import Person from './Person'
class PersonList extends React.Component {
render() {
const people = [
{ name: 'Dana', hair: 'blonde' },
{ name: 'Nichole', hair: 'long' },
{ name: 'Davey', hair: 'long gone' }
]
return (
<div>
<h2>People</h2>
{
people.map((person => <Person person={person} />))
}
</div>
)
}
}
export default PersonList
Not every React Component needs to have state. Many simply render a bit of props
and UI. For such components, we don’t need to instantiate a whole class that inherits from React.Component
, we can simply write a function that accepts props
as an argument and returns the markup we need.
For instance, in the previous example, the Person
component can easily be re-written as a Stateless Functional Component.
function Person (props) {
return (
<li>Hello, {props.person.name}!</li>
)
}
// Or...
const Person = (props) => <li>Hello, {props.person.name}!</li>
Prior to ES6, there were many competing ways to export and import JavaScript modules. The most common were CommonJS and AMD. Luckily ES6 defined a specification for standardizing module export and import.
There are two types of exports from any JS file - named and default. The important thing to remember is that there can only be one default export per module, but there can be as many named exports as you want.
myModule.js
export const myNumber = 8
export function sayHi () {
console.log('hello')
}
export default class MyClass {
add (a, b) {
return a + b
}
}
The main difference is how they are imported. Default exports get the most concise syntax:
import MyClass from 'myModule'
const classInstance = new MyClass()
classInstance.add(1, 2) // => 3
Since there can be only one default export per module, the name by which you import the default export is not important - you can name it whatever you want. For instance, instead of importing as MyClass
, we could have said import LuftBallons from 'myModule'
, and it would have worked just fine. To read more about default and named exports, click here.
Named exports get a slightly more verbose syntax for importing, and the names are important (otherwise it can’t determine what you want to import).
import { myNumber, sayHi } from 'myModule'
console.log(myNumber) // => 8
sayHi() // => 'hello'
If you need to import a named export under a different name—if, for example, you have another import or local variable with the same name—you can specifiy a different name using as.
import { myNumber as num, sayHi as yo } from 'myModule'
console.log(num) // => 8
yo() // => 'hello'
You can also combine default and named imports in the same line.
import MyClass, { myNumber, sayHi } from 'myModule'
Property initializers are a Stage 3 proposal for ECMAScript, meaning that they’re a candidate, but requires further refinement and feedback from implementations and users before it becomes part of the standard. Facebook itself is already using these techniques in production, however.
From the proposal:
“Class instance fields” describe properties intended to exist on instances of a class (and may optionally include initializer expressions for said properties).
We can take advantage of this in React.
Read more: Using ES7 property initializers in React
We can use a property initializer to set the initial value of state without writing a constructor:
class Song extends React.Component {
state = {
versesRemaining: 5,
}
}
We can even set default props and use those in the initial state:
class Song extends React.Component {
static defaultProps = {
autoPlay: false,
verseCount: 10,
}
state = {
versesRemaining: this.props.verseCount,
}
}
Combining property initializers and arrow functions gives us a convenient way to auto-bind this
, since arrow functions inherit this
from the scope in which they are declared (lexical scoping):
class Something extends React.Component {
handleButtonClick = (ev) => {
// `this` is bound correctly!
this.setState({ buttonWasClicked: true });
}
}
chat-static
content. There should be approximately one CSS file per component.SignIn
component with a form that takes a user name.state
of the App
component.state.user
is not set, show the SignIn
component.state.user
is set, show the Main
component.Hint: You need to figure out how to do conditional rendering.