こんにちは。Webエンジニアのkaoruです。
今回は週間天気コンポーネントの中の処理を子コンポーネントとして切り出してみます。
【前回】フリーAPIで天気情報を取得する (Wheather-app実装 3)
ボタン押下で天気情報取得
前回導入したAPIが150回/日を超えると(微量な)料金がかかるため、ボタンアクションで動くようにします。
Reactの再レンダーをミスして無限ループさせてしまうことがあるので、初期処理にAPIを置いとくのが怖いためです。
useMemo() / useCallback()など何度も呼ばなくする関数もHooksには用意されているのですが、追々としておきます。
スペル修正
なんと…
アプリ名にも入れている「天気」の英語スペルを間違えてました…
恥ずかし……><
一括置換はちょっと危ない
ファイルをプロジェクト全体や置換対象が多いと、一括置換はちょっと危険だと個人的に思っています。
大文字小文字判定を含めるかで結果は変わりますし、予期せぬ置換が効いてbugが埋め込まれてしまうこともあります。
ちょっと面倒くさいですが、目検しながら置換した方が安全です。
リポジトリ名変更は意外と簡単にできる ε-(´∀`*)ホッ
リモートのリポジトリ名
GitHubの[Setting]から簡単に変更できます。
ローカルのリポジトリ名
プロジェクトの.git/configファイルを書き換えればOKです。
$ vi .git/config
$ git remote -v //確認
天気 コードから気象を判別
今回投稿の本題ですね。
APIで取得した天気コードから気象名(晴れなど)に変換します。
APIの天気コード(Weather API Codes/Icons)
変換処理の為にWeather.ts ファイルを作成します。
Typescriptなので.tsです。
全種類を使うと天気の日本語にすることが少し大変なので、5種類ぐらいに絞ります。
コンポーネントを細分化
「週間天気を表示する」コンポーネント一つで表現していました。

「一つの曜日天気を表示する」を一つのコンポーネントにしてしまった方が良さそうです。
曜日毎に表示する処理は同じですし、コンポーネントにしてしまえば別の箇所に天気を表示する時など再利用もできます。

新たにWeatherDay.tsxを作成して、.map()でループで呼び出します。
{forecasts.map((forecast, index) => (
<WeatherDay
key={index}
day={forecast.day}
datetime={forecast.datetime}
weather={forecast.weather}
icon={forecast.icon}
/>
))}
渡す中身は配列情報として、useStateで初期値を入れておきます。
const initialWeather = {'day':7, 'datetime':'-', 'weather':'-', 'icon': '-'}
const [forecasts, setForecasts] = useState<PropsWeatherDay[]>(
Array.from(
{length: 7}, (_,i) => initialWeather
)
)
WeatherDay.tsx のprops情報を型としておき、ここでの初期値にも型として使用しています。ここで過不足がないかチェックができますね。
export type PropsWeatherDay = {
day: number,
datetime: string,
weather: string,
icon: string
}
ところでAPIから取得される日付は”2020-08-08″のような結果になります。
JavaScriptでは変換が標準でないので自分で加工します。
const splits = forecastDay['datetime'].split('-')
const datetime = splits[1] + '/' + splits[2]
週間天気を初期非表示にする
displayプロパティで非表示にする
週間天気は display: flex; で表示しています。
まずは display: none; にして非表示します。
styled-componentsを動的に変更する
[天気情報]ボタンを押したら週間天気情報を表示するようにしたいです。
styled-componentsコンポーネントへ渡したpropsでCSSを動的に変えてみます。
const Container = styled.div<{ visibleWeek: boolean}>`
display: ${props => ( props.visibleWeek ? 'flex' : 'none!important' )};
...
`
const [visibleWeek, setVisibleWeek] = useState<boolean>(false)
... <Container visibleWeek={visibleWeek}>
今回の学び
TypeScriptエラー
型指定に準じた実装ができていないとエラーが起きるわけですが、エラーメッセージが直積的でない時があります。
エラーメッセージから追うと「何を言っているんだ?」となったりしますので、型をちゃんと指定できているのか疑ってしまうのもアリですね。
図を描くのにVSCode draw.ioエクステンションが便利!
draw.ioは前から有名でしたけど、VSCodeでも扱えるようになったみたいです!
参考:VSCodeでDraw.ioが使えるようになったらしい!
VSCodeの拡張機能「Draw.io Integration」をインストールして、.dioファイルを作ればすぐに試せます!
便利ですね!
今日はここまで。
では、また〜。
コメント