Help us understand the problem. What is going on with this article?

【React】ToDoアプリを発展させよう【非同期処理】

More than 1 year has passed since last update.

:star: 関連

:star: 目標

  • Reactで作ったToDoアプリに機能を付け足していきます。
  • 今回は起動時に非同期処理でTodoをsetするようにします。
  • 見本:GitHub

todo-app4.gif

:star: 手順

:pencil: データ取得先を用意する

:pencil2: data.json

public/data.json
[
  {
    "title": "Hello, React!",
    "desc": "Reactはじめました"
  },
  {
    "title": "Hello, Redux!",
    "desc": "Reduxもはじめました"
  }
]

  • publicディレクトリにデータの入ったjsonファイルを作成します。ここからデータを取得することで、模擬的に非同期処理を実装します。
  • titleとdesc以外は決まった値なので、App.jsでsetするようにしましょう。

:pencil2: App.js

src/App.js
...

  constructor() {
    super()
    const todos = []
    this.state = {
      isLoading: false,
      hasError: false,
      todos: todos,
      countTodo: todos.length + 1,
    }
  }

...
  • constructorのTodoの中身を消去しておきます。
  • これから使うisLoadingとhasErrorをstateに追加します。

:pencil: 非同期処理の実装

:pencil2: App.js

src/App.js
...

  fetchData(url) {
    this.setState({ isLoading: true })
    fetch(url)
      .then((response) => {
        console.log(response)
        if (!response.ok) {
          throw Error(response.statusText);
        }
        this.setState({ isLoading: false })
        return response
      })
      .then((response) => response.json())
      .then((data) => {
        let countTodo = this.state.countTodo
        const todos = data.map(data => {
          const todo = Object.assign({}, data, { id: countTodo++, done: false })
          return todo
        })
        this.setState({ todos, countTodo })
      })
      .catch(() => this.setState({ hasError: true }))
  }

...
  • 関数fetchData()を定義し、非同期処理の中身を記述します。まず、 isLoading: trueというstateをsetし、データロード中であることを定めます。
  • fetch()メソッド.then()を使うことで段階を踏んで処理ができます。
  • 1つ目の.thenではresponseのokプロパティでアクセスの判定をします。trueの場合は正常にアクセスできているので、isLoadingをfalseにします。
  • 2つ目の.thenでは.json()メソッドでresponseがjsonであることを定義します。一行のアロー関数なので自動的にreturnされています。
  • 3つ目の.thenでは渡されたjsonデータをもとにtodoを組み立てています。Object.assign()は第1引数を{}とすることで、第2引数以降をmerge(結合)した新しいObjectを生成します。
  • どこかで処理がうまくいかなかった時、 catch()が呼ばれるため、hasError: trueというstateをsetします。

:pencil2: App.js

src/App.js
...

        <TodoList
          todos={this.state.todos}
          setTodoStatus={this.setTodoStatus.bind(this)}
          isLoading={this.state.isLoading}
          hasError={this.state.hasError}
          />

...
  • TodoListコンポーネントにisLoadingとhasErrorのStateを渡すのを忘れないように。

:pencil2: TodoList.js

TodoList.js
...

  render() {

    if (this.props.isLoading) {
      return <h2>loading . . . </h2>;
    }

    if (this.props.hasError) {
      return <h2>error</h2>;
    }

...
  • renderの中にisLoadingかhassErrorがtrueだった時の処理を追記します。

:pencil: 非同期処理を起動時に呼び出す

:pencil2: App.js

src/App.js
...

  componentDidMount() {
    this.fetchData('data.json');
  }

...
  • 最後にfetchData()を起動時に呼び出すようにします。componentDidMount()はcomponentがDOMに追加された後で自動的に呼ばれるため、これを利用しましょう。
  • この中で先ほど定義したfetchData()を呼び出し、引数にdata.jsonを渡します。
  • これで、起動時に一瞬「Loading...」が表示されてTodoが表示されます。jsonの書き方がおかしかったりすると「Error」が表示されます。

:star2: 以上で非同期処理は完成です!

todo-app9.gif

  • 内容に不備等ありましたら、お手数ですがコメントにてお願いします。

:star: 参考

mikan3rd
なんでも自分で作ってみたい盛りのエンジニア3年生。 ReactとPythonがちょっと書ける。
https://lapras.com/public/PSOCHNH
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした