Laravel + React: Posting Threads
Tags: react, laravel, javascript, php
Published: 2018-01-12 23:39:15

---
title: "Laravel + React: Posting Threads"
published: true
description: Have you been wondering how to get started with using React in your Laravel projects? In this first lesson in a new series, we'll start creating the back-end for creating threads and add a React and Axios powered form for writing and posting new threads.
tags: react,laravel,javascript,php
canonical_url: https://www.nathanheffley.com/blog/laravel-react-posting-threads
cover_image: https://thepracticaldev.s3.amazonaws.com/i/uve933inzq4k4j8hipzr.png
---

*Originally posted on [nathanheffley.com](https://www.nathanheffley.com/blog/laravel-react-posting-threads)*

*This is the first lesson in a series on how to create a forum using Laravel and React. If you haven't read the introduction where we [plan out the forum](https://www.nathanheffley.com/blog/laravel-react-planning-a-forum) you should check it out first!*

To get started with a forum, the first thing we need is the ability to create accounts, login, and create threads. Thankfully, Laravel comes with the Artisan `make:auth` command, which we'll be taking advantage of. Since this is covered pretty thoroughly other places, like in the [Laravel Authentication documentation](https://laravel.com/docs/5.5/authentication), I won't go over it again. Just know that I simply ran the `php artisan make:auth` command and didn't change any of the related files.

## Creating New Threads

The first goal in making a forum will be allowing users to publish threads. With the default authentication system we get a `/home` route and page. We'll make use of this to show a user important information, like threads they've created and notifications they've received. For right now though, we'll add a sidebar with a form to create a new page. The template is pretty simple, so replace what's in the auto-generated template with our new home page.

```html
@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-5 col-md-offset-7">
            <div id="create-thread"></div>
        </div>
    </div>
</div>
@endsection
```

That div with an id of `create-thread` is where our React form will be going. Using React for something simple like a form may seem like a little bit of overkill, but it will allow us to add extra functionality as we move forward and starting out we can make use it to submit an Ajax request instead of forcing the user to load a whole new page. As we add more components to this page, you'll see just how useful using React for all of these interactive pieces can be.

Before we move on to creating the actual React code, lets quickly go over the back-end code that will be powering the creation of new threads.

## The Back-End Functionality

To actually create threads, we'll need a database migration. For right now, we need nothing more than an `author_id` column to reference who created the thread, as well as a title and content column. In the future we'll be adding more columns, but this is good enough to get us started. You can check out [the full migration on GitHub](https://github.com/NathanHeffley/react-forum/blob/251939322e9d0ad9558721907f8809ac11bd442e/database/migrations/2018_01_11_193047_create_threads_table.php). If you're following along, make sure to create that migration (I recommend just running `php artisan make:migration create_threads_table --create=threads` and editing it to match my file) and refresh your database.

Since threads will be an actual model that we'll be interacting with, we'll need a model as well. Starting out simple, the only thing I've put into the model is a `$fillable` property so that we avoid mass-assignment exceptions and an Eloquent relationship for accessing the threads author (and of course I added the matching relationship in the User class as well, you can [view that diff here](https://github.com/NathanHeffley/react-forum/commit/1bde7f36b7d0bc809c6ee85279766dbbf53d99cb#diff-36f1184e0453df972dab51127e08458f)). [Here is the Thread class](https://github.com/NathanHeffley/react-forum/blob/251939322e9d0ad9558721907f8809ac11bd442e/app/Thread.php).

And finally, none of this would be very useful if we didn't also have a controller to handle incoming requests. You can create a blank controller with `php artisan make:controller ThreadsController` and then add these few functions.

This one is pretty straightforward and will simply show a single thread.

```
<?php

public function show(Thread $thread)
{
    return view('threads.show', compact('thread'));
}
```

This is where we'll actually be storing new threads. First we validate that the title and content data values are present. Then we actually create the thread with the values and also set the `author_id` to be the id of the currently authenticated user.

```
<?php

public function store(Request $request)
{
    $request->validate([
        'title' => 'required',
        'content' => 'required',
    ]);

    $thread = Thread::create([
        'author_id' => \Auth::user()->id,
        'title' => $request->title,
        'content' => $request->content
    ]);

    return response($thread, 201);
}
```

Now that you've seen the two useful functions, go back up to the top of the controller and add a constructor. This is simply to ensure only authenticated users can make a POST request to create a thread. Since we'll be adding more functions in the future, I decided it was best to just require authentication on everything except simply viewing a thread.

```
<?php

public function __construct()
{
    $this->middleware('auth')->except('show');
}
```

Finally, we just need some routes for creating and viewing threads and calling these controller functions. Throw these two routes into your `route/web.php` file to handle that.

```
<?php

Route::get('/threads/{thread}', 'ThreadsController@show');
Route::post('/threads', 'ThreadsController@store');
```

## Creating Threads With React

Now that the back-end is all setup and ready to go, lets create that form component!

First, go into your `resources/assets/js` folder and open up `app.js`. In there you'll see a line that pulls in the Example component. Go ahead and change that so it pulls in a more descriptive file.

```javascript
require('./components/CreateThread');
```

Go into that components folder and rename the Example.js file to be CreateThread.js. This will be our form component.

By default, you should see that the file imports React and ReactDOM. Since we're going to making Ajax requests from this component, we'll also require Axios (which comes configured by default in every Laravel project).

```javascript
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import axios from 'axios';
```

First we'll update what comes in the file by default and then add in our own functions to get the functionality we need. Make sure to update the class name definition from Example to CreateThread and do the same for the ReactDOM.render at the end. We need to check if the page has the `create-thread` id element that we will use anywhere we want this component to load. Since a page will only ever have one of these forms, this simple check will work just fine and is the perfect starting place for our first 

```javascript
export default class CreateThread extends Component {
    // Omitted for brevity right now.
}

if (document.getElementById('create-thread')) {
    ReactDOM.render(<CreateThread />, document.getElementById('create-thread'));
}
```

Now that the basic setup stuff is taken care of, we can work on rewriting the render method. We'll have the component always output itself as a self-contained panel. The majority of this code is just Bootstrap divs and styling. The important things to pay attention to are the `onChange` attributes on the input and textarea elements, and the `onClick` attribute on the button.

```react
render() {
    return (
        <div className="panel panel-default">
            <div className="panel-heading">Create a New Thread</div>

            <div className="panel-body">
                <form>
                    <div className="form-group">
                        <label htmlFor="new-thread-title">Title</label>
                        <input id="new-thread-title" className="form-control" onChange={this.changeTitle}></input>
                    </div>
                    <div className="form-group">
                        <label htmlFor="new-thread-content">Title</label>
                        <textarea id="new-thread-content" className="form-control" onChange={this.changeContent} rows="8"></textarea>
                    </div>
                </form>
            </div>

            <div className="panel-footer">
                <button className="btn btn-primary" onClick={this.postThread}>
                    Publish
                </button>
            </div>
        </div>
    );
}
```

Now that we have the render function all taken care of, we need to create those `changeTitle()`, `changeContent()`, and `postThread()` functions.

The title and content functions are easiest, since they'll just be updating the components state. The `event` parameter is automatically passed to the function by React because of how the `onChange` event attribute is handled. With the `event` object we simply select the `target` which will be either the input or textarea element and then select the value from that.

```javascript
changeTitle(event) {
    this.setState({title: event.target.value});
}

changeContent(event) {
    this.setState({content: event.target.value});
}
```

The `postThread()` function is a bit more involved, but we'll start out with the most basic Axios call we can get away with for right now. We'll come back to this function in the future when we add some new features and options for posting threads.

```javascript
postThread() {
    axios.post('/threads', {
        title: this.state.title,
        content: this.state.content
    })
    .then(response => {
        this.setState({title: '', content: ''});
        document.getElementById('new-thread-title').value = '';
        document.getElementById('new-thread-content').value = '';
    });
}
```

If you've ever worked with Axios before then this function will be pretty straight-forward. Even if you haven't used it before, I'm sure you're all smart enough to figure it out. We're simply using Axios to make a POST request to the `/threads` path on our site which we set up earlier to accept POST requests and send them to the ThreadsController. In that POST request we're passing the title and content data which is stored in the components state (put there by the `changeTitle` and `changeContent` functions). Axios works using [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) so that after a request has been completed and a response is received, the `then` function gets called. Inside of that we reset the components state to have empty values and clear out the title and content inputs.

The final bit of this controller that we need is a constructor. We need to setup the initial state of the component, and also bind `this` to each of the functions we created. I go over why we need to doing this binding in my post on [getting started with React](https://www.nathanheffley.com/blog/getting-started-with-react-in-laravel-5-5).

```javascript
constructor(props) {
    super(props);
    this.state = {
        title: '',
        content: '',
    };

    this.postThread = this.postThread.bind(this);
    this.changeTitle = this.changeTitle.bind(this);
    this.changeContent = this.changeContent.bind(this);
}
```

If you want to see the whole file, [view it on GitHub](https://github.com/NathanHeffley/react-forum/blob/251939322e9d0ad9558721907f8809ac11bd442e/resources/assets/js/components/CreateThread.js).

That's it! We now have a component that can create threads on our forum using React and Axios. Visit your project (or [clone it from GitHub]()) and go to the `/home` path to see the form. If you try submitting it you might not see much happen, but if you check out your browser's developer tools you should be able to see a POST request going to `/threads`. After submitting a thread, try visiting `/threads/1` and you should be able to see the first thread you created.

This lack of feedback isn't very user friendly, so in the next lesson we'll work on creating some sort of alert component to tell users that their thread was successfully created and give them a link to view it.