React 101

30 minutes introduction to React framework

by Piotr Staniów

(and Paweł Kamiński)

20 kwiecień 2018 Hotel Dębowy - Chapter day stuff :)

JSX

  const element = <h1>Hello, world!</h1>;

Introducing JSX

Embedding Expressions in JSX

  ReactDOM.render(
   <h1>
     Hello, {formatName(user)}!
   </h1>,
   document.getElementById('root')
 );

React app has single root

Introducing JSX

JSX is an Expression Too

 function getGreeting(user) {
   if (user) {
     return <h1>Hello, {formatName(user)}!</h1>;
   }
   return <h1>Hello, Stranger.</h1>;
 }

Introducing JSX

JSX Represents Objects

  const element = (
     <h1 className="greeting">
       Hello, world!
     </h1>
   );
  const element = React.createElement(
   'h1',
   {className: 'greeting'},
   'Hello, world!'
 );
 // Note: this structure is simplified
   const element = {
     type: 'h1',
     props: {
       className: 'greeting',
       children: 'Hello, world!'
     }
   };

Introducing JSX

Writing Components

The main purpose of web frameworks is to encapsulate custom HTML elements logic

Functional and Class Components

 function Welcome(props) {
   return <h1>Hello, {props.name}</h1>;
 }
  
class Welcome extends React.Component {
  render() {
   return <h1>Hello, {this.props.name}</h1>;
 }
}

Components and Props

Rendering a Component

  
  function Welcome(props) {
     return <h1>Hello, {props.name}</h1>;
   }
   const element = <welcome name="Sara">;
   ReactDOM.render(
     element,
     document.getElementById('root')
   );

Components and Props

Composing Components

 function Welcome(props) {
   return <h1>Hello, {props.name}</h1>;
 }
  
function App() {
   return (
     <div>
       <Welcome name="Sara"/>
       <Welcome name="Cahal"/>
       <Welcome name="Edite"/>
     </div>
   );
 }
  
ReactDOM.render(
   <App />,
   document.getElementById('root')
 );

Components and Props

Extracting Components

 function Comment(props) {
 return (
  <div className="Comment">
    <div className="UserInfo">
      <img className="Avatar"
        src={props.author.avatarUrl}
        alt={props.author.name}
      />
      <div className="UserInfo-name">
        {props.author.name}
      </div>
    </div>
    <div className="Comment-text"> {props.text} </div>
    <div className="Comment-date"> {formatDate(props.date)}</div>
  </div>
 );
}

Components and Props

Extracting Components

 function Avatar(props) {
   return (
     <img className="Avatar"
       src={props.user.avatarUrl}
       alt={props.user.name}
     />
   );
 }
  function UserInfo(props) {
   return (
     <div className="UserInfo">
       <Avatar user={props.user} />
       <div className="UserInfo-name">
         {props.user.name}
       </div>
     </div>
   );
 }

Components and Props

Extracting Components

 function Comment(props) {
   return (
     <div className="Comment">
       <div className="UserInfo">
         <Avatar user={props.author} />
         <div className="UserInfo-name">
           {props.author.name}
         </div>
       </div>
       <div className="Comment-text">{props.text}</div>
       <div className="Comment-date">{formatDate(props.date)}</div>
     </div>
   );
 }

Components and Props

Extracting Components

  function Comment(props) {
   return (
     <div className="Comment">
       <UserInfo user={props.author} />
       <div className="Comment-text">
         {props.text}
       </div>
       <div className="Comment-date">
         {formatDate(props.date)}
       </div>
     </div>
   );
 }

Components and Props

Extracting Components

 class FancyInput extends React.Component {
   constructor(props) {
     super(props); // This is required
     const { initialValue } = props;
     this.state = {
       value: initialValue,
     };
   }
   render() {
     const { value } = this.state;
     return <input type="text" value={value} />;
   }
 }

Adding complexity - event handling

 class FancyInput extends React.Component {
   constructor(props) {
     super(props); // This is required
     const { initialValue } = props;
     this.state = {
       value: initialValue,
     };
   }
   handleChange(event) {
     console.log('Input value has changed!', event.target.value);
   }
   render() {
     const { value } = this.state;
     return <input type="text" value={value} onChange={this.handleChange}/>;
   }
 }

Adding complexity - updating state

  class FancyInput extends React.Component {
   constructor(props) {
     super(props); // This is required
     const { initialValue } = props;
     this.state = { value: initialValue, somethingElse: 5 };
   }
   handleChange(event) {
     console.log('Input value has changed!', event.target.value);
     this.setState({ value: event.target.value}); // Asynchronous!
   }
   render() {
     const { value } = this.state;
     return ;
   }
 }

Adding complexity - styling

 class FancyInput extends React.Component {
   constructor(props) {
     super(props); // This is required
     const { initialValue } = props;
     this.state = { value: initialValue, somethingElse: 5};
   }
   handleChange = ({target: {value}}) => {
     this.setState({ value }); // Asynchronous!
   }
   render() {
     const { value } = this.state;
     const styles = {
       border: `3px solid ${value === 'zielony' ? 'green' : 'red'}`,
     };
     return <input type="text" value={value} style={style} onChange={this.handleChange} />
   }
 }