Moniruzzaman Saikat

Posted Sep 29, 2026 · 5 min read · 1 view

Report

React Basics for Beginners: Components, State, and Fetching Data

React is one of the most popular ways to build user interfaces, and it is a common requirement in job listings. The concepts can feel overwhelming at first, but you only need a few core ideas to build real things.

In this tutorial you will set up a React project with Vite, learn components, props, state, and effects, and build a small app that fetches and filters data from an API.

What you need

  • Node.js 18 or newer installed
  • Basic knowledge of HTML, CSS, and modern JavaScript (arrow functions, destructuring, map)
  • A code editor such as VS Code

Step 1: Create a project with Vite

Vite is a fast build tool and the standard way to start a new React project today:

npm create vite@latest devs-list -- --template react
cd devs-list
npm install
npm run dev

Open the local URL that appears in your terminal. You will see the starter page. The important files are:

  • index.html: the single HTML page
  • src/main.jsx: the entry point that mounts your app
  • src/App.jsx: your root component

Open src/App.jsx, delete everything inside, and replace it with:

export default function App() {
  return <h1>Hello, BD Devs</h1>;
}

The page updates instantly, without a manual refresh.

Step 2: Understand components and JSX

A React component is just a function that returns UI. The syntax that looks like HTML is called JSX. Create src/Greeting.jsx:

export default function Greeting() {
  return <p>Welcome to the community!</p>;
}

Use it inside App.jsx:

import Greeting from './Greeting';

export default function App() {
  return (
    <div>
      <h1>Hello, BD Devs</h1>
      <Greeting />
    </div>
  );
}

A few JSX rules to remember:

  • Component names must start with a capital letter
  • A component must return a single root element (wrap siblings in a div or a fragment <>...</>)
  • Use className instead of class
  • Put JavaScript expressions inside curly braces: {name}

Step 3: Pass data with props

Props let a parent component send data to a child. Update Greeting.jsx:

export default function Greeting({ name, city }) {
  return <p>Hi {name} from {city}!</p>;
}

Then use it with different values:

<Greeting name="Rahim" city="Dhaka" />
<Greeting name="Karim" city="Chattogram" />

Props flow in one direction, from parent to child, and a child should never modify them. This one way flow makes React apps easier to understand.

Step 4: Add state with useState

Props are inputs. State is data that a component owns and that changes over time. When state changes, React re-renders the component.

import { useState } from 'react';

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

  return (
    <button onClick={() => setCount(count + 1)}>
      Clicked {count} times
    </button>
  );
}

useState(0) returns the current value and a function to update it. Two important rules:

  1. Never change state directly. Write setCount(count + 1), not count = count + 1.
  2. When the new value depends on the old one, use the updater form: setCount(prev => prev + 1).

For objects and arrays, create a new copy instead of mutating:

setUsers([...users, newUser]);                       // add
setUsers(users.filter(u => u.id !== idToRemove));    // remove

Step 5: Render lists and handle input

Let us build a searchable list. Create src/DevList.jsx:

import { useState } from 'react';

const devs = [
  { id: 1, name: 'Rahim', skill: 'Laravel' },
  { id: 2, name: 'Karim', skill: 'React' },
  { id: 3, name: 'Nadia', skill: 'Python' },
];

export default function DevList() {
  const [query, setQuery] = useState('');

  const filtered = devs.filter(d =>
    d.skill.toLowerCase().includes(query.toLowerCase())
  );

  return (
    <div>
      <input
        value={query}
        onChange={e => setQuery(e.target.value)}
        placeholder="Search by skill"
      />
      <ul>
        {filtered.map(dev => (
          <li key={dev.id}>{dev.name} - {dev.skill}</li>
        ))}
      </ul>
    </div>
  );
}

Notice two things. The input is a controlled component, meaning its value comes from state. And every list item needs a stable, unique key, such as a database ID. Avoid using the array index as a key when the list can change order.

Step 6: Fetch data with useEffect

Real apps load data from APIs. Side effects like fetching belong in useEffect:

import { useState, useEffect } from 'react';

export default function Users() {
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const controller = new AbortController();

    fetch('https://jsonplaceholder.typicode.com/users', {
      signal: controller.signal,
    })
      .then(res => {
        if (!res.ok) throw new Error('Request failed');
        return res.json();
      })
      .then(data => setUsers(data))
      .catch(err => {
        if (err.name !== 'AbortError') setError(err.message);
      })
      .finally(() => setLoading(false));

    return () => controller.abort();
  }, []);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Something went wrong: {error}</p>;

  return (
    <ul>
      {users.map(u => <li key={u.id}>{u.name}</li>)}
    </ul>
  );
}

Key points:

  • The empty dependency array [] means the effect runs once after the first render
  • Always handle loading and error states, not only the happy path
  • The cleanup function cancels the request if the component unmounts, which prevents state updates on components that no longer exist

In development, React Strict Mode runs effects twice to help you spot bugs. That is normal and does not happen in production.

Common beginner mistakes

  • Mutating state directly, which causes the UI not to update
  • Missing keys in lists, which triggers warnings and odd behavior
  • Missing dependencies in useEffect, which causes stale data. If your effect uses a value, it usually belongs in the dependency array
  • Putting everything in one giant component. Split UI into small, focused components
  • Fetching data on every render by forgetting the dependency array

Where to go next

Once these basics feel comfortable, learn these in order:

  1. useRef and useContext for shared values
  2. Custom hooks to reuse logic
  3. React Router for multiple pages
  4. A data fetching library such as TanStack Query
  5. TypeScript with React

Final thoughts

React looks large, but almost everything builds on the same idea: your UI is a function of your data. Change the state, and React updates the screen. Practice by building small projects, like a todo list, a weather app, or a job board, and the concepts will stick faster than any tutorial.

What was the hardest React concept for you to grasp? Tell us in the comments.

Be the first to react
0

Written by

Moniruzzaman Saikat

Software Engineer at TheSoftking Ltd

Software engineer who loves building useful things, solving hard problems, and turning ideas into scalable products. Always learning, shipping, and experimenting with new tech.

Founding MemberNew MemberProlific Writer

14 articles · Dhaka Bangladesh · Joined Sep 2026

Discussion (0)

Sign in to join the discussion.