Vapor Trail

明るく楽しく元気よく

React Native入門:ニュースアプリを作りながら覚えよう/Hooks対応 2020年版 をやった

React Native入門:ニュースアプリを作りながら覚えよう/Hooks対応 2020年版

仕事ではPHPでWebアプリを作っていたがモバイルアプリ作ってみたかったのでReact Native入門した。 React Nativeの技術書もあるが出版して1年以上経過しているものしかないのでReduxとHooksも学べるUdemyの講座をやることにした。

学んだこと

Componentとpropsによるデータの受け渡し

Vue.jsと似ていたのですんなり理解できた。

外部APIからデータの取得

axios使ってるだけ

React Hooks

関数コンポーネントでもstateを持つことができるようになったらしいが、Hooks以前でなにに困っていたのかを知らないのでクラスコンポーネントではなく関数コンポーネントで書くことにどういう意味があるのかピンとこなかった。関数コンポーネントだと簡潔に書けるということと副作用が起こりにくいらしいので基本的に関数コンポーネントを使用すべきだということはわかった。

useStateとuseEffect

関数コンポーネントでstateを利用するにはフックを使用する。

  const [loading, setLoading] = useState(false);
  // 外部APIからデータを取得する
  const fetchArticles = async () => {
    setLoading(true);
    try {
      const response = await axios.get(URL);
      setArticles(response.data.articles);
    } catch (error) {
      console.error(error);
    }
    setLoading(false);
  };

  // useState([])は初期値
  const [articles, setArticles] = useState([]);
  // useEffectで第2引数に空の配列を渡すと、第1引数がmount, unmount時に実行されるが更新時には実行されない
  useEffect(() => {
    fetchArticles();
  }, []);

ステートフックの利用法 – React

5分でわかるReact Hooks - Qiita

関数コンポーネントはクラスとどう違うのか?

  • React Navigationによるページ遷移

  • Redux

コンポーネントでActionをDispatchする
Actionのtypeはアクションの種類、payloadは渡したいデータ
ActionがDispatchされるとReducerが以前のStateと渡されたデータから新しいStateを合成してStoreに持つ

VueのActionを通してMutationをCommitするみたいな

Component

  const dispatch = useDispatch();
  // storeからuser stateを取得する
  const user = useSelector((state) => state.user);
  const { clips } = user;
  // 記事がclip済みかどうか判定する
  const isClipped = () => {
    return clips.some((clip) => clip.url === article.url);
  };
  // 記事がクリップされていれば削除されていなければ追加する
  const toggleClip = () => {
    if (isClipped()) {
      dispatch(deleteClip({ clip: article }));
    } else {
      dispatch(addClip({ clip: article }));
    }
  };

Action

export const ADD_CLIP = "ADD_CLIP";
export const DELETE_CLIP = "DELETE_CLIP";
/**
 * 渡されるclipの中身はarticle object
 */
export const addClip = ({ clip }) => {
  return {
    // actionの種類
    type: ADD_CLIP,
    // payloadは渡したいデータ
    clip,
  };
};

export const deleteClip = ({ clip }) => {
  return {
    type: DELETE_CLIP,
    clip,
  };
};

Reducer

import { ADD_CLIP, DELETE_CLIP } from "../actions/user";

const initialState = {
  clips: [],
};

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case ADD_CLIP:
      return {
        // 前回のstate
        ...state,
        // スプレッド演算子で前回のstateを展開、新しいデータを配列に追加する
        clips: [...state.clips, action.clip],
      };
    case DELETE_CLIP:
      return {
        ...state,
        clips: state.clips.filter((clip) => clip.url !== action.clip.url),
      };
    default:
      return state;
  }
};

export default reducer;

ややこしいっす

たぶんこれが一番分かりやすいと思います React + Redux のフロー図解 - Qiita

Reduxが分からない人のためにReduxを概念から説明してみる - Qiita

Reduxの永続化

Expo

できたやつ expo.io

ReactNativeの基本的な使い方を学びました。なんか作れそうな気がしてきた。