- 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.propsandthis.statemay 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
thisis 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.nameto 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
Providerand aConsumer
- Make a new context
- in
Provider.jsexport const MyContext = React.createContext();
- Create a Provider Component
- in
Provider.jsclass 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.jsimport 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.Consumeras a parent compnent, using the context that the Consumer component returns, render the component and use thecontextto grab data from the provider
-
in
componentName.jsimport {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.setStateto 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.stateorval.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