- must always have 1 and only 1 root node
- must use
className
in place ofclass
- can bind javascript with {}
- In JSX, event listener names are written in camelCase, such as onClick or onMouseOver.
- use Ternary opp for inline conditional logic
- multi-line jsx can be wrapped in
( )
- && works best in conditionals that will sometimes do an action, but other times do nothing at all.
const tasty = (
<ul>
<li>Applesauce</li>
{ !baby && <li>Pizza</li> }
{ age > 15 && <li>Brussels Sprouts</li> }
{ age > 20 && <li>Oysters</li> }
{ age > 25 && <li>Grappa</li> }
</ul>
);
const people = ['Rowe', 'Prevost', 'Gare'];
const peopleLis = people.map((person,i) =>
<li key={'person_' + i}>{person}</li>
);
// ReactDOM.render goes here:
ReactDOM.render(<ul>{peopleLis}</ul>, document.getElementById('app'))
Items in a list should be given a unique key.
- styles defined in objects use cammel case.
margin-top
->marginTop
- units can be passed as integers and will default to
px
- can inject object literals:
<h1 style={{ color: 'red' }}>Hello world</h1>
- can import shared styles from file
- create a component with
class MyComponent extends React.Component
- render components with
<MyComponent />
- must implement
render()
. returns jsx - constructor, takes props. Must call super
constructor(props){
super(props);
}
- created as a function in the component
- can be passed to child components via props
- called in child component through accessing props (can then be bound to the html-event attributes)
- should be bounded to
this
in constructor withthis.myHandler = this.myHandler.bind(this);
If you have a component class with nothing but a render function, then you can write that component as a function.
export const GuineaPigs = (props) => {
let src = this.props.src;
return (
<div>
<h1>Cute Guinea Pigs</h1>
<img src={src} />
</div>
);
}
Uncontrolled Component: a component that maintains its own internal state.
Controlled Component: A controlled component is a component that does not maintain any internal state. Since a controlled component has no state
, it must be controlled through props
validates that the passed in props are what's expected. (not needed for typescript!)
MessageDisplayer.propTypes = {
message: React.PropTypes.string
};
state: store information that the component itself can change. props: store information that can be changed, but can only be changed by a different component.
- Props are passed into the component and CANNOT Be modified!
- "Stateful" describes any component that has a state property
- "stateless" describes any component that does not.
- use
this.setState({ myObj:'val' });
-- only overwrites values passed in -- causes arender()
to fire. (thus, cannot be called fromrender()
)
- props are passed in as jsx attributes on components
<MyComponent myProp="123"
/>
- Components can contain other components inside jsx
- Every component's props object has a property named children. Accessed via
this.props.children
- If a component has more than one child between its JSX tags, then
this.props.children
will return those children in an array. However, if a component has only one child, thenthis.props.children
will return the single child, not wrapped in an array.
<BigButton>
<LilButton />
</BigButton>
You can define "default values" for props to take on when they are not explicitly set, by setting defaultProps
on your component.
MyComponent.defaultProps = {
{text:"This is a default value!"}
};
Typescript
class MyComponent extends Component<IProps, IStates> {
public static defaultProps: IProps = { /* ... */ };
// ...
}
A component "mounts" when it renders for the first time. This is when mounting lifecycle methods get called.
-
componentWillMount()
: When a component renders for the first time,ComponentWillMount
gets called right before render -
render()
: render belongs to two categories: mounting lifecycle methods, and updating lifecycle methods. -
componentDidMount()
: When a component renders for the first time,componentDidMount
gets called right after the HTML from render has finished loading.ComponentDidMount
is a good place to connect a React app to external applications, such as web APIs or JavaScript frameworks.
The first time that a component instance renders, it does not update. A component updates every time that it renders, starting with the second render.
Whenever a component instance updates, it automatically calls all five of these methods, in order:
-
componentWillReceiveProps(nextProps)
: typically used for comparing incoming props to current props or state, and deciding what to render based on that comparison. -
shouldComponentUpdate(nextProps, nextState) : boolean
: used to preventrender()
from being called (return false
) based on next values -
componentWillUpdate(nextProps, nextState)
: The main purpose of componentWillUpdate is to interact with things outside of the React architecture. You cannot call this.setState from the body of componentWillUpdate! -
render()
-
componentDidUpdate(prevProps, prevState)
: usually used for interacting with things outside of the React environment, like the browser or APIs.
componentWillUnmount()
: A component's unmounting period occurs when the component is removed from the DOM.
- parent component defines a methods that calls
setState()
. Methods is binded to this. - parent passes method to prop
- The child receives the passed-down function, and uses it as an event handler.
Each Component should have only 1 job. One stateless component display information, and a different stateless component offer the ability to change that information.
//parent
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = { name: 'Frarthur' };
this.changeName = this.changeName.bind(this);
}
changeName(newName) {
this.setState({
name: newName
});
}
render() {
return (
<div>
<Child onChange={this.changeName} />
<Sibling name={this.state.name} />
</div>
);
}
});
//child
export class Child extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
const name = e.target.value;
this.props.onChange(name);
}
render() {
return (
<div>
<select
id="great-names"
onChange={this.handleChange}>
<option value="Frarthur">Frarthur</option>
<option value="Gromulus">Gromulus</option>
</select>
</div>
);
}
}
//Display
export class Sibling extends React.Component {
render() {
const name = this.props.name;
return (
<div>
<h1>Hey, my name is {name}!</h1>
</div>
);
}
}
If a component has to have state
, make calculations based on props
, or manage any other complex logic, then that component shouldn't also have to render HTML-like JSX.
Instead of rendering HTML-like JSX, the component should render another component. It should be that component's job to render HTML-like JSX.
//container class
const GUINEAPATHS = [
'https://s3.amazonaws.com/codecademy-content/courses/React/react_photo-guineapig-1.jpg',
'https://s3.amazonaws.com/codecademy-content/courses/React/react_photo-guineapig-2.jpg'
];
class GuineaPigsContainer extends React.Component {
constructor(props) {
super(props);
this.state = { currentGP: 0 };
this.interval = null;
this.nextGP = this.nextGP.bind(this);
}
nextGP() {
let current = this.state.currentGP;
let next = ++current % GUINEAPATHS.length;
this.setState({ currentGP: next });
}
componentDidMount() {
this.interval = setInterval(this.nextGP, 5000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
render() {
let src = GUINEAPATHS[this.state.currentGP];
return <GuineaPigs src={src} />;
}
}
ReactDOM.render(
<GuineaPigsContainer />,
document.getElementById('app')
);
//display class
export class GuineaPigs extends React.Component {
render() {
const src = this.props.src;
return (
<div>
<h1>Cute Guinea Pigs</h1>
<img src={src} />
</div>
);
}
}