Lesson 14-Preact State and Props

State

State is internal component data that can change, triggering a re-render when updated.

Concepts and Usage

  • Concept: State holds data within a component. When state changes, Preact automatically re-renders the affected component.
  • Usage
import { h, Component } from 'preact';

class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }

  increment = () => {
    this.setState({ count: this.state.count + 1 });
  };

  render() {
    return (
      <div>
        <p>Count: {this.state.count}</p>
        <button onClick={this.increment}>Increment</button>
      </div>
    );
  }
}
  • setState: The method to update state. Preact merges the new and old state objects, triggering a re-render only when necessary.
  • Avoid Direct State Mutation: Never modify this.state directly; always use setState to ensure proper state updates.

State vs Props

  • Control: Props are controlled externally, enforcing a unidirectional data flow; state is managed internally, reflecting the component’s internal condition.
  • Use Cases: Use props for static or externally passed data; use state for dynamic, internally maintained data.
  • Reusability: Prop-based components are more reusable as they don’t rely on external conditions; stateful components may require more context.

Lifecycle Methods

Understanding lifecycle methods is crucial when managing state and props. Key methods related to state and prop changes include:

  • componentDidMount: Called after the initial render, ideal for DOM operations or data fetching.
  • shouldComponentUpdate: Determines if the component should update based on new props or state.
  • getDerivedStateFromProps: Called during re-rendering to compute new state from updated props or state.
  • getSnapshotBeforeUpdate: Invoked before DOM updates to capture a snapshot of the current state.
  • componentDidUpdate: Called after updates, suitable for DOM operations or additional requests.

Hook API (Supported in Preact X and Later)

Preact introduced Hooks, enabling state and lifecycle management without class components.

  • useState: Manages state in function components.
import { useState } from 'preact/hooks';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}
  • useEffect: Replaces lifecycle methods like componentDidMount, componentDidUpdate, and componentWillUnmount.
  • Other Hooks: Includes useContext, useReducer, useRef, and more for additional functionality.

Props

Concept: Props are a way to pass data from a parent component to a child component. They are read-only and cannot be modified within the child component.

Usage

function ChildComponent({ name }) {
  return <p>Hello, {name}!</p>;
}

function ParentComponent() {
  return <ChildComponent name="Alice" />;
}

Default Props: Specify default prop values for a component.

ChildComponent.defaultProps = {
  name: 'Stranger'
};

Type Checking: Use propTypes for static type checking to improve code quality.

import PropTypes from 'prop-types';

ChildComponent.propTypes = {
  name: PropTypes.string.isRequired
};

Combining State and Props

Here’s a complete example demonstrating how to use state and props together in Preact.

App.js

import { h } from 'preact';
import Counter from './Counter';

const App = () => (
  <div>
    <Counter initialCount={5} />
  </div>
);

export default App;

Counter.js

import { h, Component } from 'preact';

class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = { count: props.initialCount || 0 };
  }

  increment = () => {
    this.setState({ count: this.state.count + 1 });
  };

  decrement = () => {
    this.setState({ count: this.state.count - 1 });
  };

  render() {
    return (
      <div>
        <p>Count: {this.state.count}</p>
        <button onClick={this.increment}>Increment</button>
        <button onClick={this.decrement}>Decrement</button>
      </div>
    );
  }
}

export default Counter;

Explanation:

  1. The App component passes an initialCount prop to the Counter component.
  2. The Counter component uses props.initialCount to initialize its state and updates the state when buttons are clicked.

Share your love