Skip to content

Instantly share code, notes, and snippets.

@tjwudi tjwudi/README.md
Last active Aug 4, 2017

Embed
What would you like to do?
Roundtable - React & Redux

We use CodeSandbox for this interactive session.

JSX

JSX is just syntax sugar for some React JavaScript API. For example, the following JSX code ...

<DashboardUnit data-index="2">
  <h1>Scores</h1>
  <Scoreboard className="results" scores={gameScores} />
</DashboardUnit>;

gets transpiled to ...

React.createElement("div", { className: "red" }, "Children Text");
React.createElement(MyCounter, { count: 3 + 5 });

React.createElement(
  DashboardUnit,
  { "data-index": "2" },
  React.createElement("h1", null, "Scores"),
  React.createElement(Scoreboard, { className: "results", scores: gameScores })
);

It's basically writing html in JavaScript. There are some difference though, for example, instead of using class, you should use className instead because class is ES6 reserved keyword.

Coding Practice 1

In Hello.js, change the JSX syntax to plain JS and see what happens.

import React from 'react';

export default ({ name }) => React.createElement(
  'h1', {}, `Welcome to ${name}`
);

You can add props as the second parameter.

import React from 'react';

export default function ({ name }) {
  	const props = {
    	'className': 'underlined'	
    };
    return React.createElement(
        'h1', props, `Welcome to ${name}`
    );
};

And add CSS to the html.

<style>
  .underlined {
    text-decoration: underline;
  }
</style>

React Component

A JavaScript object that transfrom props and states into html. Let's try to add a barebone component to our App.

class TodoList extends React.Component {
  render () {
    return (
    	<div>
        	This is a TodoList
        </div>
    );
  }
};

const App = () => (
  <div style={styles}>
    <Hello name="CodeSandbox" />
    <h2>This is an awesome Todo List!</h2>
    <TodoList/>
  </div>
);

We can access props via this.props in a component instance. render is the function that converts state (see below) and props into JSX (aka html).

class TodoList extends React.Component {
  render () {
    return (
    	<div>
        	This is a TodoList. It's made by {this.props.author}
        </div>
    );
  }
};

const App = () => (
  <div style={styles}>
    <Hello name="CodeSandbox" />
    <h2>This is an awesome Todo List!</h2>
    <TodoList author="diwu"/>
  </div>
);

Every compoenent has a object state. This is ... it's state! =)

We can initial state in constructor and update state using setState. setState will trigger another component lifecycle so render gets called again.

class TodoList extends React.Component {
  constructor(props) {
    super(props)
    
    this.state = {
      'likeCount': 0
    }
  }
  
  onLike() {
    this.setState({
      'likeCount': this.state.likeCount + 1
    })
  }
  
  render () {
    return (
      	<div>
          <div>
              This is a TodoList. It's made by {this.props.author}. {this.state.likeCount} people liked it!
          </div>
          <div>
              <button onClick={this.onLike.bind(this)}>Like!</button>
          </div>
        </div>
    )
  }
}

Single State Model

Note: I made up the term "Single State Model" :')

The idea here is to have a single global state and pass it to the top level component (in our case, <App/>).

let store = {
  'todos': [
  	// {'description': 'this is a description'}
  ]
};

And yes, we don't need a 'done' key in that todo object. TODOs are never done.

Let's add a form for adding todo.

<form>
  <input type="text" name="todo-description" id="todo-description" onChange={this.onTodoDescriptionChange.bind(this)}></input>
    <button onClick={this.onAdd.bind(this)}>Add</button>
</form>

We will also need to add a todoDescription key to the component state.

this.state = {
  'likeCount': 0,
  'todoDescription': '',
}

onTodoDescriptionChange is called when the <input/> text is changed, onAdd is called when new todo item is added.

onAdd() {
  store['todos'].push({
    'description': this.state.todoDescription,
  })
  this.forceUpdate()
}

onTodoDescriptionChange(evt) {
  this.setState({
    'todoDescription': evt.target.value,
  })
}

Finally we get to render the list of todos to the view using {store.todos.map}.

<ul>
    {store.todos.map(function (todo) {
      return <li>{todo.description}</li>
    })}
</ul>

Practice: Move likeCount to global state.

We sometimes will still have component level state because they just don't make sense to be global (like the todoDescription above).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.