LoginSignup
0
1

More than 1 year has passed since last update.

railsとreactでtodoアプリを作る!(part4)

Last updated at Posted at 2021-11-03

作成するアプリについて

railsとreactを用いたtodoアプリになります。
https://todo-app-rails-react.herokuapp.com/todoes

(part1)

(part2)

(part3)

(part5)

開発環境

  • ruby3.0
  • rails6.1(rails6以上必須)
  • react17.0.2
  • vscode

アプリの作成手順

  1. サーバーサイドの実装
    1. アプリの作成
    2. turbolinksの無効化
    3. モデル&テーブルの作成
    4. 初期データの作成
    5. top#indexの作成
    6. todoes_controllerの作成
    7. ルーティングの設定
    8. application_controllerの設定
    9. application.html.erbに追記(part1でここまで完了済み)
  2. フロントサイドの実装
    1. componentsフォルダの作成
    2. リセットcssと共通cssの設定
    3. index.jsxの記述
    4. フロントの実装準備
    5. App.jsの記述(part2でここまで完了済み)
    6. TodoList.jsの記述(part3でここまで完了済み)
    7. NewTodo.jsの記述
    8. EditTodo.jsの記述

それでは進めていきましょう!

アプリ作成

2. フロントサイドの実装

2.7 NewTodo.jsの記述

まずは一気に見た目の調整をしていきましょう!TodoList.jsと似ているのでサクッといきます!

app/javascript/components/NewTodo.js
import React from 'react'
import styled from 'styled-components'

export const NewTodo = () => {
  return (
    <>
      <h1>NewTodo</h1>
      <InputAndNew>
        <Input type="text" placeholder="NewTodo..." />
        <NewBtn >AddNewTodo</NewBtn>
      </InputAndNew>
    </>
  )
}

const InputAndNew = styled.div`
  display: flex;
  justify-content: space-between;
  align-items: center;
`

const Input = styled.input`
  font-size: 20px;
  width: 100%;
  height: 40px;
  margin: 10px 0;
  padding: 10px;
`

const NewBtn = styled.button`
  width: fit-content;
  height: 40px;
  background: #ccffcc;
  border: none;
  font-weight: 500;
  margin-left: 10px;
  padding: 5px 10px;
  border-radius: 3px;
  cursor: pointer;
`

import styled from 'styled-components'を忘れずに記述しましょう!

以下のようになりましたでしょうか?
スクリーンショット 2021-11-01 17.54.25.png

では、機能面の実装に移ります!

まずはinput関連ですね。

app/javascript/components/NewTodo.js
import React, { useState } from 'react'
import styled from 'styled-components'

export const NewTodo = () => {

  const initialTodoStatus = {
    id: null,
    content: "",
    is_completed: false
  }

  const [todo, setTodo] = useState(initialTodoStatus)

  const onChangeNewTodo = (e) => {
    const { name, value } = e.target;
    console.log(value) //入力した文字列
    console.log(name) //content 
    setTodo({ ...todo,[name]: value });
        //todoを展開して、カラム名を指定してvalueに更新します。
  }

  return (
    <>
      <h1>NewTodo</h1>
      <InputAndNew>
        <Input  
          type="text" 
          placeholder="NewTodo..." 
          required
          value={todo.name}
          onChange={onChangeNewTodo}
          name="content" />
        <NewBtn >AddNewTodo</NewBtn>
      </InputAndNew>
    </>
  )
}

//以下省略

import React, { useState } from 'react'になってますので気をつけてください!

続けて、AddNewTodoボタンの実装に移ります。

app/javascript/components/NewTodo.js
//以上省略
const InputNewTodo = (e) => {
    const { name, value } = e.target;
    console.log(value)
    console.log(name)
    setTodo({ ...todo,[name]: value });
  }

  const onClickSaveTodo = () => {
    const newVal = {
      content: todo.content
      //contentカラムにinputで記述したものを代入しています。
    };
    axios.post('/api/v1/todoes', newVal)
    .then(resp => {
      setTodo({
        id: resp.data.id,
        content: resp.data.content,
        complete: resp.data.complete
      });
      //レスポンスで渡されたデータを代入していきます。
      props.history.push("/todoes");
      //TodoList.jsにpropsとして情報を渡します。
    })
    .catch(e => {
      console.log(e)
    })
  }

  return (
    <>
      <h1>NewTodo</h1>
      <InputAndNew>
      <Input 
          type="text" 
          placeholder="NewTodo..." 
          required
          value={todo.name}
          onChange={InputNewTodo}
          name="content" />
        <NewBtn onClick={onClickSaveTodo}>AddNewTodo</NewBtn>
      </InputAndNew>
    </>
  )
}
//以下省略

動くか確認してみましょう!
スクリーンショット 2021-11-01 20.54.01.png
AddNewTodoをクリック!
スクリーンショット 2021-11-01 20.54.33.png
うまくいってますね!

続いてtoastifyの実装をしていきます!イケてるポップアップを簡単に実装できます!

app/javascript/components/NewTodo.js
import axios from 'axios'
import React, { useState } from 'react'
import styled from 'styled-components'
import { toast } from 'react-toastify'
import "!style-loader!css-loader!react-toastify/dist/ReactToastify.css"//toastifyのcss

toast.configure();//toastifyを有効にするには必須(忘れがち)

export const NewTodo = (props) => {

  const notify = () => {
    toast.success("Todo successfully created!", {
      position: "bottom-center",
      hideProgressBar: true
    });
  }

  const initialTodoStatus = {
    id: null,
    content: "",
    is_completed: false
  }

  const [todo, setTodo] = useState(initialTodoStatus)

  const InputNewTodo = (e) => {
    const { name, value } = e.target;
    console.log(value) 
    console.log(name) 
    setTodo({ ...todo,[name]: value });
  }

  const onClickSaveTodo = () => {
    const newVal = {
      content: todo.content
    };
    axios.post('/api/v1/todoes', newVal)
    .then(resp => {
      setTodo({
        id: resp.data.id,
        content: resp.data.content,
        complete: resp.data.complete
      });
      notify();//toastifyの表示タイミング
      props.history.push("/todoes");
    })
    .catch(e => {
      console.log(e)
    })
  }
//以下省略

import { toast } from 'react-toastify' import "!style-loader!css-loader!react-toastify/dist/ReactToastify.css" toast.configure(); notify(); が追記されています。

toastifyのcssは開発環境のみであれば以下でも問題ないですが、本番環境ではstyle崩れをおこす可能性があります。 import 'react-toastify/dist/ReactToastify.css'

では確認してみましょう!
スクリーンショット 2021-11-01 21.01.34.png

スクリーンショット 2021-11-01 21.02.04.png

できてますね!

今回はここまでとします。お疲れ様でした。次回が最終partとなります!

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1