iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 30
0
Modern Web

Zero to hero with React.js系列 第 30

【Day 30 React】Redux+API 製作 meme generator—— 完結篇

繼昨天 export 之後我們就可以來撰寫 reducer。把 NEW_MEME 加進來

import { RECEIVE_MEMES, NEW_MEME } from '../actions';

接下來要寫 reducer 回調函數,我們要回傳兩個參數 StateAction,透過 action 的 type 決定接下來的動作。當 action type = NEW_MEME 時,便更新 state 的內容。

function myMemes(state = [], action){
    switch(action.type) {
      case NEW_MEME:
        state = [...state, action.meme],
        return state;
      default:
        return state;
    }
}

記得要將剛剛新增的 myMemes 加到 combineReducer function 中,接下來要把 myMemes 的 action creator 加在 MemeItem component 之上,它允許我們把 meme actions 的 creation 附加到我們之前寫好的 postMeme function。進到 MemeItem.jsnewMeme 這個 action import 進來

import { newMeme } from '../actions';

我們必須把我們的 component 和 redux 做連結,因此這邊把 connect function 引進來

import { connect } from 'react-redux';

export 的地方也要加上 connect,不過現在還沒有 state props 因此先給 null

export default connect(null, {newMeme})(MemeItem);

在 postMeme function 裡,我們要把 this.props 的值傳進去,透過 const 我們可取得 text0 和 text1 變數

 postMeme(){
    const { text0, text1 } = this.props;
  }
  

現在,我們建造一個 meme object,這個物件裡面包含 meme id 以及 input value (也就是 text0,text1 的值)


椰絲!現在可以看到 console.log 有抓到 text0,text1,template_id 的值!!!
GETTING CLOSER!!!

建置 post meme action

創建一個 postMemeJson function

function postMemeJson(params){

}

這個階段,我們需要身份驗證資訊才有辦法從 API 中再次取出圖片,所以必須把 secrets.js 裡面定義的 API 的帳號與密碼引入,這在後面產出 meme 時,可以讓這些 object 包含我的帳號與密碼(import 要寫在最前面)

import { username, password } from './secrets';

要進到 API 必須要有一組特殊 url code,因此我們要把我們的 params 調整成符合的 body string。Object.key(params) 會取的所有 params 裡的 key 值,map 每一個 key 並產出一個 encode 結果,中間用 = 去和 API 裡的 key 值比對,這樣的寫法就可以取得 encode 後的 URL。.join('&'); 可以把每一個屬性值用 & 區隔開來。

function postMemeJson(params){
  params["username"] = username;
  params["password"] = password;

  const bodyParams = Object.key(params).map(key => {
    return encodeURIComponent(key) + '=' + encodeURIComponent(params[key])
  }).join('&');
}

現在我們準備好可以呼叫 fetch function 了,fetch 方法幫我們抓取到與 fetch meme json function 裡相同的 url。我們必須定義我們要用的是 POST 方法,並且定義這個方法的內容,也就是 'application/x-www-form-urlencoded'。在 POST 裡,header 是允許我們定義要傳進 API 的特定規範。透過 .then() 回傳 json

return fetch('https://api.imgflip.com/caption_image',{
    method: "POST",
    header: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: bodyParams
 }).then(response => response.json());
 

接下來要新增 createMeme function,把 new_meme_object 傳回 postMemeJson,接著我們要用 new_meme action creater dispatch 從 handler 傳過來的 new_meme

export function createMeme(new_meme_object){
  return function(dispatch){
    return postMemeJson(new_meme_object)
      .then(new_meme => dispatch(newMeme(new_meme)))
  }
}

接著更新 MemeItem component 裡的 newMeme,改用 createMeme 取代它

import { createMeme } from '../actions';

  postMeme(){
    const { text0, text1 } = this.props;
    const memeObj = {
      template_id : this.props.meme.id,
      text0,
      text1
    }
    this.porps.createMeme(memeObj);
  }
  


椰乎!在 myMemes 裡看到我輸入的文字以及新產生的 url,success: true 表示成功!
我把 url 單獨開啟分頁,瓦~~~哈哈哈哈這臉神韻完全發揮得淋漓盡致XDDDD

新圖呈現在頁面上

熬了真久~終於來到最最後一個步驟啦!因為使用者並不會自己開啟 console.log 尋找他自己做的 memes 的網址(除了很懂網頁機關的各位可能會XD)
我接下來要讓這個圖片直接呈現在頁面上~

剛剛我們的 array 取名叫 Mymemes,那麼我就來新增一個 Mymemes component
建立 MyMeme 類別

class MyMemes extends Component{
  return (){
    <div>
      {
        this.props.myMemes.map((meme, index) => {
          return(
            <img 
              key={index}
              src={meme.data.url}
              alt="my-meme"
              className="my-meme-img" 
            />
          )
        })
      }
    </div>
  }
}

讓 memes 透過 prop 更新 state

 function mapStateToProps(state){
  return {
    myMemes: state.myMemes
  }
}

export connect

export default connect(mapStateToProps, null)(MyMemes);

最後,到 parent component App.js 加上 MyMeme tag,加在標題下方

import MyMemes from './MyMemes';

<h2> Welcome to the Meme Generator!</h2>
<MyMemes />

yaaaaaaaaaaaaaaaa
yoooooooooooooooo
有哩

完整專案連結 Github


上一篇
【Day 29 React】Redux+API 製作 meme generator—— Part3
系列文
Zero to hero with React.js30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
zivtor
iT邦新手 4 級 ‧ 2018-09-14 17:19:06

Yoooooo~
目前公司剛好急需ReactJS人才rrrrrr!!
有興趣的話可以站內私訊詳談喔~

我要留言

立即登入留言