React learning - component interaction

React learning (1) - JSX

React learning (2) - react component

Return HTML elements and components

The render() method of a class component can return any JSX, including a mixture of HTML elements and custom React components.

In this example, we return a <logo / > component (<logo / > is defined elsewhere)

class Header extends React.Component {
  render() {
    return (
      <div>
        <Logo />
        <h1>Hello World</h1>
      </div>
    );
  }
}

React component export

The common practice is to put each React component in its own file, then export it with export, and then import it in other places as needed. This file organization helps make components reusable.

In this example, we may have two files, one is App.js, which is the top-level component of our application, and the other is Clock.js, a sub component.

// Clock.js
import React from 'react';
 
export class Clock extends React.Component {
  render() {
    // ...
  }
}
 
// App.js
import React from 'react';
import { Clock } from './Clock';
 
class App extends React.Component {
  render() {
    return (
      <div>
        <h1>What time is it?</h1>
        <Clock />
      </div>
    );
  }
}

this.props

React class components can access their props through this.props object.

In the following example code, we see that the <hello> component has a firstName when it is rendered. It is accessed with this.props.firstName in the render() method of the component.

This should present the text "Hi there, Kim!"

class Hello extends React.Component {
  render() {
    return <h1>Hi there, {this.props.firstName}!</h1>;
  }
}
 
ReactDOM.render(<Hello firstName="Kim" />, document.getElementById('app'));

defaultProps

The defaultProps object of a React component contains default values, which are used without passing prop. If a prop is not passed to a component, it will be replaced with the value in the defaultProps object.

In the example code, defaultProps is set so that the configuration file has an alternate configuration file image without setting.

In the following code, the <myfriends> component should render two profiles: a Profile image named Jane Doe using the setting, and a Profile image named John Smith using the default.

class Profile extends React.Component {
  render() {
    return (
      <div>
        <img src={this.props.profilePictureSrc} alt="" />
        <h2>{this.props.name}</h2>
      </div>
    );
  }
}
 
Profile.defaultProps = {
  profilePictureSrc: 'https://example.com/no-profile-picture.jpg',
};
 
class MyFriends extends React.Component {
  render() {
    return (
      <div>
        <h1>My friends</h1>
        <Profile
          name="Jane Doe"
          profilePictureSrc="https://example.com/jane-doe.jpg"
        />
        <Profile name="John Smith" />
      </div>
    );
  }
}

Prop

Components can pass information to other components. When a component passes information to another component, it passes one or more attributes through Prop.

The example code demonstrates the use of attributes in props. SpaceShip is a component and ride is an attribute. The SpaceShip component will receive rides in its props.

<SpaceShip ride="Millennium Falcon" />

this.props.children

The props object of each component has an attribute named children. Using this.props.children will return everything between the JSX tags at the beginning and end of a component.

render() {
    console.log(this.props.children)
};

Bind this

In React Class components, it is common to pass an event handler function to an element in the render() method. If these methods update the state of the component, this must be bound so that these methods can correctly update the state of the entire component.

In the following example code, we bound this Changename (), so that our event handler program can work.

class MyName extends React.Component {
  constructor(props) {
    super(props);
    this.state = { name: 'Jane Doe' };
    this.changeName = this.changeName.bind(this);
  }
 
  changeName(newName) {
    this.setState({ name: newName });
  }
 
  render() {
    return (
      <h1>My name is {this.state.name}</h1>
      <NameChanger handleChange={this.changeName} />
    )
  }
}

Call super() in constructor

The React Class component should call super(props) in its constructor function to correctly set its this.props object.

// WRONG!  This is wrong!
class BadComponent extends React.Component {
  constructor() {
    this.state = { favoriteColor: 'green' };
  }
  // ...
}
 
// RIGHT!  That's right!
class GoodComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { favoriteColor: 'green' };
  }
  // ...
}

this.setState()

React Class components can change their state through this.setState(). You should always use this.setState() instead of modifying this.state object directly.

this.setState() receives an object and merges it with the current state of the component. If there are properties that do not belong to the object in the current state, these properties will not change.

In the following example code, we see this Setstate() is used to update the state of the Flavor component from "Apple" to "Banana".

class Flavor extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      favorite: 'Apple',
    };
  }
 
  render() {
    return (
      <button
        onClick={(event) => {
          event.preventDefault();
          this.setState({ favorite: 'Banana' });
        }}
      >
        No, my favorite is vanilla
      </button>
    );
  }
}

Dynamic data in components

React components can receive dynamic information from props, or use state to set their own dynamic data. Props is passed down by the parent component, while state is created and maintained by the component itself.

In this example, you can see that this.state is set in the constructor function, used in render(), and updated through this.setState().

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { showPassword: false };
  }
 
  render() {
    let text;
    if (this.state.showPassword) {
      text = `The password is ${this.props.password}`;
    } else {
      text = 'The password is a secret';
    }
 
    return (
      <div>
        <p>{text}</p>
        <button
          onClick={(event) => {
            event.preventDefault();
            this.setState((oldState) => ({
              showPassword: !oldState.showPassword,
            }));
          }}
        >
          Toggle password
        </button>
      </div>
    );
  }
}

Component state in constructor

The React Class component stores its state as a JavaScript object. This object is initialized in the constructor function of the component.

In this example, the component stores its state in this.state.

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      favoriteColor: 'green',
      favoriteMusic: 'Bluegrass',
    };
  }
 
  render() {
    // ...
  }
}

Do not change state when rendering

When you update the state of a React component, it will automatically re render. This means that you should not update the state in the render function, because it will cause an infinite loop.

In this example, we show some bad code, calling this.setState() in its render() method.

class BadComponent extends React.Component {
  constructor(props) {
    super(props);
    this.count = 0;
  }
  render() {
    // Don't write this code. It's not good
    this.setState({ count: this.state.count + 1 });
    return <div>The count is {this.state.count}</div>;
  }
}

Reference: Codecademy

Tags: Javascript Vue.js Front-end Web Development

Posted by lemmin on Sun, 31 Jul 2022 22:14:05 +0530