Skip to content

Instantly share code, notes, and snippets.

@claritee
Last active February 26, 2018 10:29
Show Gist options
  • Save claritee/8ce9798d78b6bacd2bc872dea68952ac to your computer and use it in GitHub Desktop.
Save claritee/8ce9798d78b6bacd2bc872dea68952ac to your computer and use it in GitHub Desktop.
Learn ReactJS

React

Notes in WIP

Components

Components are created by calling createClass on the React object

render() method includes the markup to draw the component on the page

Example:

var ButtonApp = React.createClass({
    render: function(){
        return (
            <input type="submit" />
        );
    }
});

Or

class CommentBox extends React.Component {
...
}

JSX

Javascript Syntax Extension

What it does: write JS with XML-like tags

Nesting Components

Include the child component

e.g.

App
 | 
 |_ ButtonForm
 

<ButtonForm/>

Using createClass

var ButtonForm = React.createClass({
    render: function(){
        return (
             <!-- html ... -->
        );
    }
});

Include the <ButtonForm/> component:

var App = React.createClass({
    render: function(){
        return (
             <!-- html ... -->
            <ButtonForm />
        );
    }
});

Render the App component using React.render

React.render(<App />,  document.getElementById("content"));

Props & State

state - internal to the app props - external and get passed around (not controlled by the component)

Props

Props are immutable

Evaluation

{`${this.props.author}'s picture`}

In:

class Comment extends React.Component {
  render() {
    return(
      <div className="comment">
        <img src={this.props.avatarUrl} alt={`${this.props.author}'s picture`}  />
        ...
      </div>
      );
  }
}

Example:

var BUTTONTEXT = "Click the button";
<App text={BUTTONTEXT} />
  • text is the prop
  • {BUTTONTEXT} is evaluated in { }

{this.props.text} will be how App references text prop

Example

var BUTTONTEXT = "Click the damn button";

var ButtonForm = React.createClass({
	render: function(){
		return (
			<!-- html -->
			<h3>{this.props.text}</h3>
		);
    }
});

var App = React.createClass({
	render: function(){
		return (
			<!-- html -->
			<ButtonForm text={this.props.text} />
		);
	}
});

React.render(<App text={BUTTONTEXT} />,  document.getElementById("content"));

State

The state is stored within the component (private, cannot be accessed by child) State is mutable

  • Initialising state - getInitialState()
  • Setting state - this.setState()

Recommended to use a method - to only update the property, not entire object

this.setState(..)

Then component re-renders

Example:

class Comment extends React.Component {
  constructor() {
    super();
    this.state = {
      isAbusive: false
    };
  }

  render() {
    return (...)
  }

  _toggleAbuse(event) {
    event.preventDefault();
  }

Example

var App = React.createClass({
    getInitialState: function(){
        return {
            active: true
        }
    },
    handleClick: function(){
        this.setState({
            active: !this.state.active
        });
    },
    
    render: function(){
        var buttonSwitch = this.state.active ? "On" : "Off";
        return (
                <input type="submit" onClick={this.handleClick} />
                <p>{buttonSwitch}</p>
        );
    }
});
React.render(<App />,  document.getElementById("content"));

Where should state live

Data flows from parent to child
  • Minimise stateful components
  • Components further down hierarchy should be passed props
Stateful components are usually higher level, while the stateless are lower level.

Inverse data flow

When child needs to change state in the parent

Button:

The button calls the App's onUserClick function to change state

var ButtonForm = React.createClass({
    render: function(){
        return (
            <div>
                <input type="submit" onClick={this.props.onUserClick} />
                <h3>You have pressed the button {this.props.counter} times!</h3>
            </div>
        );
    }
});

App

var App = React.createClass({
    getInitialState: function(){
        return {
            counter: 0
        }
    },
    onUserClick: function(){
        var newCount = this.state.counter + 1;
        this.setState({
            counter: newCount
        });
    },
    render: function(){
        return (
            <div>
                <h1> Welcome to the counter app!</h1>
                <ButtonForm counter={this.state.counter} onUserClick={this.onUserClick} />
            </div>
        );
    }
});

refs and findDOMNode

Changing the DOM directly

(Not updating the component or accessing state/props)

React.findDOMNode(component)

Example

<input ref="textField" ... />

To access

this.refs.textField
var ButtonForm = React.createClass({
        focusOnField: function(){
            React.findDOMNode(this.refs.textField).focus();
        },
        render: function(){
            return (
                <input type="submit"
                value="Focus on the input!" 
                onClick={this.focusOnField} />
            );
        }
    });
    ...
});

var App = React.createClass({
	render: function() {
		return 
			<ButtonForm />
			...
    }
)};
    
React.render(<App />,  document.getElementById("content"));

key attribute

When: Creating components dynamically

Example

  1. todos - List of strings, stored in App's state
  2. Traverse through the list and construct as <li> elements
  3. On render - display <li> elements in <ul>
var App = React.createClass({
    getInitialState: function(){
        return {
            todos: ["get food","drive home","eat food", "sleep"] 
        }
    },
    render: function(){
        var todos = this.state.todos.map(function(todo,index){
            return <li key={index}>{todo}</li>
        });             
        return (
            <div>
                <h1> Welcome to the ToDo list!</h1>
                <ul>
                    {todos}     
                </ul>
            </div>
        );
    }
});

DOM Manipulation

INDIRECT

event -> update state object (by user code) -> DOM updates (by React)

Set initial state in the constructor

  • call super() first
  • then set initial state this.state
class CommentBox extends React.Component {
  constructor() {
    super();
    this.state = {
      showComments: false
    };
  }
  render() {
    ...
  }
  ...
}

Binding to Events

Example 1:

//inside render() of react component
<button onClick={this._handleClick().bind(this)}>click</button>
// method in the react component
_handleClick() {
  this.preventDefault();
  this.setState({
    showComments: !this.state.showComments
  });
}

Example 2:

<form onSubmit={this._handleSubmit.bind(this)}> ... </form>
_handleSubmit(event) {
  event.preventDefault();
}

Passing functions as params

Example 1:

In render() of react component

<input placeholder="Name:" ref={(input) => this._author = input} />

Example 2:

On render() on the react component

<textarea
  placeholder="Comment:"
  ref={textarea => this._body = textarea}
  onKeyUp={this._getCharacterCount().bind(this)}
></textarea>

As a method in the react component

_getCharacterCount() {
    this.setState({characters: this._body.value.length});
  }

Example Exercises

https://github.com/ReactForBeginners/exercise1-todo

Resources

Flow

https://flow.org/en/docs/react/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment