- create-react-app
- JSX
- Components
- Rendering Elements
- Props
- PropTypes
- State
- Events
- Forms
- Refs
- Context
- Lifecycle Methods
- to start:
create-react-app <app-name>
- comes with built in functionality:
React | libraries for creating react componentents and rendering them |
webpack | links together js files |
jest | automated test runner |
- a syntax extension to javascript. Used with react to descritbe what the UI should look like.
- Babel compiles JSX down to
React.createElement()
calls
- can accept props but cannot have state
function Welcome(props) {
return <h1>Hello, {props.name}</h1>
}
- can have state plus some additional features
class Welcome extends Component {
render() {
return <h1>Hello, {this.props.name}</h1>
}
}
const element = <Welcome name="Sara" />;
ReactDOM.render(
element,
document.getElementById('root')
);
-
an object that gives components the ability to receive data from the parent component; make components reusable
-
to give a component props
// class component class DummyComponent extends React.Component { render() { return <div>Hello {this.props.name}</div>; } } // functional component function Welcome(props) { return <div>Hello {props.name}</div> }
-
when using the component:
<DummyComponent name="Jane" /> <DummyComponent name="Joe" />
-
when passing multiple props down from components, you can wrap them in an object and use the spread notation.
<Component x={} y={} z={} />
can become...
var props = { x: 1, y: 1, z:1 }; <Component {...props} />
- a class property of component
- sets default props for the class
class CustomButton extends React.Componet { //... } CustomButtton.defaultProps = { color: 'blue' } render() { return <CustomBttton /> // props.color is set to blue }
- checks if props are a certain type
- install the propType library
$ npm install prop-types
import PropTypes from 'prop-types';
- declare prop types of a function:
class Greeting extends React.Component { render() { return ( <h1>Hello, {this.props.name}</h1> ); } } Greeting.propTypes = { name: PropTypes.string };
- other prop types:
optionalArray: PropTypes.array,
optionalBool: PropTypes.bool,
optionalFunc: PropTypes.func,
optionalNumber: PropTypes.number,
optionalObject: PropTypes.object,
optionalString: PropTypes.string,
optionalSymbol: PropTypes.symbol,
- to make required:
requiredFunc: PropTypes.func.isRequired,
- for more information click here
- an object that determines how a component renders and behaves
- (local) state: cannot be accessd outside of the component and can only be used and modified inside the component
- when the state changes, the component re-renders
- declaring state:
class Test extends Component { constructor(props) { super(props); this.state = { something: "value" } } }
- to reference state
<h1>{this.state.something}</h1>
- to reference state
- asynchronous state: because
this.props
andthis.state
may be updated asynchronously, you should
- a react.Component method that changes a componemt's state
this.setState(updater, callback)
updater
: can be a object or a functioncallback
: optional, runs after setState is completed and the component is rendered
- updater as a function:
this.setState((prevState, props) => { return { counter: prevState.counter + props.step } })
- events in React are similar to handling events on DOM elements, except:
- React events are named in camelCase
- With JSX you pass a function as the event handler rather than a string
<button onClick={doSomething}>
- to prevent defailt in JSX you must call
preventDefault
function doSomething(e) { e.preventDefault() //... }
- e is a synthetic event - a cross-browser wrapper around the browser's native event
- if other arguments are used, e will be passed as the last argument
- it's also worth noting that
this
is not bound to class methods by default. To bindthis
:- use the
public class fields syntax
:
handleClick = () => { // handle click with stuff here }
- bind in the constructor:
this.handleClick = this.handleClick.bind(this);
- use the arrow function (not recommended):
<button onClick={(e) => this.handleClick(e)}>
- use the
- in DOM elements, form keep some internal state.
- In React we should use
controlled components
- by default
<input>
,<textarea>
and<select>
maintain their own state based on user input. In react, state should only be updated withsetState()
. We alsways want to make the value of our elements equals to the components appropriate state for that value.handleChange(e) { this.setState({ value: e.taget.value }) } //... <input value={this.state.value} onChange={this.handleChange} />
- by default
- textarea:
<textarea value={this.state.value} onChange={this.handleChange}> text goes here </textarea>
- select:
this.state = {selectValue: "option1"} <select value={this.state.selectValue} onChange={this.handleSelect}> <option value="option1">Option 1</option> <option value="option2">Option 2</option> <option value="option3">Option 3</option> </select>
- multiple values:
- make the name the same as the element's controlled state name, and use
event.target.name
to set the state with the computed value
- make the name the same as the element's controlled state name, and use
//...
this.state = {
inputValue: "",
selectValue: "option3"
}
//...
handleChange = (event) => {
this.setState({
[event.target.name] : event.target.value
})
//...
<input name="inputValue" type="text" value={this.state.inputValue} onChange={this.handleChange} />
<select name="selectValue" value={this.state.selectValue} onChange={this.handleChange}>
<option value="option1">Option 1</option>
<option value="option2">Option 2</option>
<option value="option3">Option 3</option>
</select>
- a direct reference to a DOM element (use sparingly)
- creating a property
constructor(props) {
super(props);
this.input = React.createRef();
}
- using callbacks:
// callback has access to the dom element <input ref={(input) => this.inputText = input} />
- to get access to the DOM element
this.inputText
- can retrieve the value, manipulate focus, etc.
this.inputText.focus() this.inputText.current.value // gets the current value
- Normally data is passed from Parent to child via props. This can get messy when the children props that need data from the parent are heavily nested.
- Context API: can inject data at any level. To do this you need a
Provider
and aConsumer
- Make a new context
- in
Provider.js
export const MyContext = React.createContext();
- Create a Provider Component
- in
Provider.js
class MyProvider extends Component { state = { name: 'jane'} render() { return ( <MyContext.Provider value={this.state.name}> {this.props.children} </MyContext.Provider> ) } }
- Set up the Provider: Import Provider and and wrap the Application in it, whenever the provider updates, its child components will also update
- in
index.js
import MyProvider from './Provider'; export class App extends Component { render() { return ( <MyProvider> <App /> </MyProvider> ) } }
- Setup the consumer to pass data whenever a component needs data from the provider, user the
contextName.Consumer
as a parent compnent, using the context that the Consumer component returns, render the component and use thecontext
to grab data from the provider
-
in
componentName.js
import {MyContext} from './Provider'; <MyContext.Consumer> {context => <div>{context}</div>} </MyContext.Consumer>
-
can pass down functions (actions) to update the state
- wrap the state and functions in an object, use
this.setState
to update state<MyContext.Provider value={{ state: this.state, makeCaps: () => this.setState({ name: this.state.name.toUpperCase() }) }}> {this.props.children} </MyContext.Provider>
- access the state with
val.state
orval.fnName
<MyProvider> <MyContext.Consumer> {val => { return ( <div> <div>Name: {val.state.name}</div> <button onClick={val.makeCaps}>MAKE CAPS</button> </div> ) }} </MyContext.Consumer> </MyProvider>
- wrap the state and functions in an object, use
-
using userinput to change the state
- in the provider, give arguments for the method that will update the state
<MyContext.Provider value={{ state: this.state, changeName: (input) => this.setState({ name: input }) }}> {this.props.children} </MyContext.Provider>
- in the provider, give arguments for the method that will update the state
-
in the consumer, pass the user input as the arg
changeName = (e, context) => { e.preventDefault(); console.log(this.state.val) context.makeCaps() context.changeName(this.state.val) } /* ... */ <MyContext.Consumer> {val => { return ( <div> <form onSubmit={(e, context) => this.changeName(e, val)}> <input val={this.state.val} onChange={(e) => this.setState({ val: e.target.value})}/> </form> </div> ) }} </MyContext.Consumer>
- a react.Component method
- by default a component rerenders when the state or props change, this causes
render()
to be called explicitely - use sparingly
- methods React calls for you
- only required method
- should not modify the component's state, should be pure and return the same results each time.
- not invoked when
shouldComponentUpdate()
returns false
- the purpose is to set the state and bind methods
- called before mounting
- invoked immediately after a component is mounted.
- a good place for loading data
- by the time its called, the component has rendered at least once
- an opportunity to render to the DOM after the component has been rendered
- called after all the children have been updated. The last thing to be executed.
- ex: an app that collects input data from the user and then updates data to the DB.
- invoked immediately before a component is updated and destroyed.
- used for cleanup - invalidating timers, canceling requests or cleaning up subscriptions
- by default this method re-renders after every state change
- can compare the current state/props to nextState and nextProps, can return false to say that the update can be stopped
- invoked right before calling the render method on initial mount and subsequent updates
- returns an object to update state or null to not update anything
- invoked right before the most recently rendered output is commited to the DOM - allows your component to capture some information from the DOM
- the value will be passed as a param to componentDidUpdate
- catches JS errors anywhere in their child component tree, log these errors and displays a fallback UI instad of a component tree that crashed
- componentWillMount
- componentWillRecieveProps(nextProps)
- componentWillUpdate