James Williams
# Install Node.js, then:
npx create-react-app my-app
cd my-app
npm start
# Visit: http://localhost:3000
// JSX
const element = <h1>Hello, CMM721!</h1>;
// With expressions
const name = 'Student';
const greeting = <h1>Hello, {name}!</h1>;
// With attributes
const button = <button className="btn" onClick={handleClick}>
Click Me
</button>;
// Multi-line
const element = (
<div>
<h1>Title</h1>
<p>Content</p>
</div>
);
// Simple component
function Welcome() {
return <h1>Hello, World!</h1>;
}
// With props
function Welcome(props) {
return <h1>Hello, {props.name}!</h1>;
}
// Arrow function
const Welcome = ({ name }) => {
return <h1>Hello, {name}!</h1>;
};
// Usage
<Welcome name="James" />
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
<button onClick={() => setCount(count - 1)}>
Decrement
</button>
</div>
);
}
// Parent component
function App() {
return (
<div>
<Greeting name="James" role="Lecturer" />
<Greeting name="Student" role="Learner" />
</div>
);
}
// Child component
function Greeting({ name, role }) {
return (
<div>
<h2>Hello, {name}!</h2>
<p>Role: {role}</p>
</div>
);
}
function PostList() {
const posts = [
{ id: 1, title: 'Django Tutorial' },
{ id: 2, title: 'React Basics' },
{ id: 3, title: 'REST APIs' }
];
return (
<ul>
{posts.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}
Create a blog interface using React components
import { useState, useEffect } from 'react';
function Posts() {
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch('http://localhost:8000/api/posts/')
.then(response => response.json())
.then(data => {
setPosts(data);
setLoading(false);
});
}, []); // Empty array = run once on mount
if (loading) return <p>Loading...</p>;
return <PostList posts={posts} />;
}
Click button to fetch posts...
// Run once on mount
useEffect(() => {
fetchData();
}, []);
// Run when 'id' changes
useEffect(() => {
fetchPost(id);
}, [id]);
// Run on every render (avoid!)
useEffect(() => {
console.log('Component rendered');
});
// Cleanup function
useEffect(() => {
const timer = setInterval(() => {
console.log('Tick');
}, 1000);
return () => clearInterval(timer); // Cleanup
}, []);
function CreatePost() {
const [title, setTitle] = useState('');
const [content, setContent] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
console.log({ title, content });
// Send to API
};
return (
<form onSubmit={handleSubmit}>
<input
value={title}
onChange={(e) => setTitle(e.target.value)}
/>
<textarea
value={content}
onChange={(e) => setContent(e.target.value)}
/>
<button type="submit">Create Post</button>
</form>
);
}
Connect React frontend to Django REST API
// Action
const increment = () => ({ type: 'INCREMENT' });
// Reducer
const counterReducer = (state = { count: 0 }, action) => {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
case 'DECREMENT':
return { count: state.count - 1 };
default:
return state;
}
};
// Create store
import { createStore } from 'redux';
const store = createStore(counterReducer);
// Dispatch action
store.dispatch(increment());
Preparation: Find 2-3 web applications to analyze
Contact: JWilliams@Staff.newman.ac.uk
Office Hours: By appointment
Resources: React Documentation, React Tutorial
Thank you for your attention!