-
Install NodeJS from https://nodejs.org
-
Install VSCode from https://code.visualstudio.com
Note: You can use another editor if you'd prefer, but VSCode works well
Recommended VSCode plugins:
-
Windows users: Restart your machine (sorry)
-
Open VSCode, and open the folder you want to work in
(we recommend creating a new folder, something like
~/src/intro-to-react
) -
Open a new terminal inside vscode
Keyboard shortcut:
Ctrl + `
-
In the terminal run the command
npx create-react-app myapp
This will download half the internet and setup a "hello world" react app
-
cd myapp
-
npm start
Congratulations, you've created your first react app! (Let's have a quick look at what was generated)
- Components are the primary building blocks of a react app. You define components, and you compose them into an app.
- Think of components as classes, they should be lowly coupled, and highly cohesive — this includes DOM structure (HTML), styling (CSS) and view logic (Javascript).
- Two types of components, functions, and classes. For this workshop, we're going to focus on classes
- You can think of the functional component as being like the
render
function of a class (it's not quite, but it helps to think of it that way)
- Open
App.js
- Change the
App
component from a function to a class - What is JSX? (it's kind of like html)
- Let's change the JSX.
- The styling is defined in
App.css
let's have a look, and change things - React is testable see
App.test.js
. We're going to skip tests today, but normally we'd use TDD when building our app.
We're building a chatroom, let's start with sending messages
-
We're building a
ChatRoom
, let's make a new component insrc/ChatRoom.js
-
All components need to have 1 "root element", and can have other elements inside. Let's create a
div
for the root. -
Add a heading for the chatroom e.g.
My Chat room
-
Add a
section
for the new message,label
,textarea
andbutton
-
Export the
ChatRoom
component and import it intoApp
. -
It looks terrible, let's add some style to it.
Note: normally we wouldn't add styles this way, because it gets difficult to manage as the app grows. There are libraries like
styled-components
which help with this, we'll have some links at the end if you want to learn more
One of the big benefits of react, is that we can reuse components.
- Add a second ChatRoom component in
App.js
- Change the
ChatRoom
component to accept aname
prop, that it renders in the heading - See that the component has rendered twice with a different heading.
- Remove the second
ChatRoom
it looks strange, but if we get far enough, we'll re-use this knowledge later.
React gives us a way to manage app state, so that we can use the data we enter in our forms.
-
Add some state to the
ChatRoom
component, we'll add asentCount
with a default value of0
. -
To use this, let's add a little note below the send button.
-
We want to update this, so lets add an
onClick
handler to the button.A few things to watch out for:
- For
sendHandler
use an arrow function to automaticallybind(this)
to the function. - Don't mutate the existing value for
sentCount
directly, but use setState to set a new value. This is an optimisation in react, if it can assume values are immutable, it can know when to update components, and when not to.
- For
This state goes away when we refresh the page, so it's not very useful. What we really want to do is save things to an API, and get them back later.
-
Add the
message
to state, and anonChange
handler to thetextarea
to update it.We want to
POST
the data to an endpoint (and luckily we've created one for you)POST https://chatapi.site/messages
expects the following JSON payload (and will fail if it doesn't get it):{ "message": "This message should come from the textarea", "user": "We passed this in via props" }
-
Use
fetch
to send the message:Use an
async function
, this will be cleanest easiest. Theoptions
argument you'll have to pass tofetch
will look something like:sendMessage = async () => { let data = { user: this.props.name, message: this.state.message }; await fetch('https://chatapi.site/messages', { method: 'POST', body: JSON.stringify(data), }); }
You can use
result.ok
to check if the response was successful, andawait response.json()
to read the response body (for debugging).Your browser's developer tools can show you what was sent, and what was received
You can now write a react app, with styling, and send data to an API.
The next step is reading data (which is easier than sending it). If we don't get here, you can do this in your own time.
-
Create a new
Message
component insrc/Message.js
-
Our
Message
component will be adiv
, it will have ap
for the message, ah5
for the author. We'll pass inmessage
andauthor
from props. -
Create another
section
in theChatRoom
for showing the existing messages. This is going to show a list of messages, rendered as components -
In our
ChatRoom
component, we want to render aMessage
component for each message. We can usemessages.map
for this (passing the correct props). It should look something like:
<section>
<h3>Messages:</h3>
{ this.state.messages.map((message) =>
(<Message message={message} />)
)}
</section>
-
We need to fetch the messages from the API! In our
ChatRoom
component, add acomponentDidMount
method that will fetch the messages fromhttps://chatapi.site/messages
and set themessages
from the response in state.Use fetch again, it should look something like
getMessages = async () => { const response = await fetch('https://chatapi.site/messages'); const responseJson = await response.json(); if (response.ok) { return responseJson.messages } else { throw new Error(`Failed to fetch messages: ${responseJson}`); } } componentDidMount = async () => { const messages = await this.getMessages(); this.setState({ messages: messages }); }
Don't forget to add
messages: []
to the initial state.
Our codebase is looking like a bit of a mess. It might make sense to clean it up a bit Recommended components to extract:
NewMessageSection
The fields for creating a new message. The new message section can also take the sendMessage
function and handlers with it, and the styling for the new message section should live with the component (e.g. in NewMessageSection.css
)
MessageList
The list of new messages. Can also include the logic for getting messages from the API. We didn't style this section yet either, so we can do that too
- React docs: https://reactjs.org/
- Official react tutorial: https://reactjs.org/tutorial/tutorial.html
- Video tutorials about react: https://egghead.io/browse/frameworks/react
- Some more project ideas: https://daveceddia.com/your-own-react-project-ideas/
- React developer tools for your browser: https://reactjs.org/blog/2015/09/02/new-react-developer-tools.html
- Styled-components: https://www.styled-components.com/
- Flexbox: https://css-tricks.com/snippets/css/a-guide-to-flexbox/
- MDN Javascript, Html, CSS docs: https://developer.mozilla.org/