前提・実現したいこと
React-Reduxで多言語対応Webアプリを作っています。
APIからJSONを取得して、JSONの中身を翻訳し、翻訳済みの文字列をstateセットし、DOMに反映することです。
発生している問題・エラーメッセージ
JSONの中身を翻訳し、stateにセットできている事までは確認できていますが、なぜか map
でループすると中身が翻訳前になってしまいます。
Redux-sagaを利用しており、流れは
componentDidMount()でAPIを叩く(/components/home.js)
→ APIから返ってきたJSONをgoogle translateで翻訳 (/sagas/index.js)
→ reducerを通して、stateにセット(/reducers/indexReducer.js)
→ mapループで要素を作成(/components/home.js)
→ DOMに反映(/components/home.js)
の流れになっています。
consoleで確認すると日本語ですが、DOMは英語になってしまいます。
該当のソースコード
/components/home.js
javascript
1import React, { Component } from 'react'; 2import HeaderComponent from './layouts/Header'; 3import FooterComponent from './layouts/Footer' 4 5// CSS 6import '../css/layout.scss'; 7 8class Home extends Component { 9 constructor(props) { 10 super(props) 11 this.state = {} 12 } 13 componentDidMount = async () => { 14 await console.log('did mount'); 15 16 await this.props.getTrips(this.props.lng) 17 await console.log(this.props.trips); 18 19 } 20 21 render() { 22 console.log('Homelng' + this.props.lng); 23 // ここでconsole.logすると翻訳済みの本文が確認できる 24console.log(this.props.trips); 25 26 let i = 0 27 // ここでループすると中身が英語に戻ってしまう 28 const contents = this.props.trips.map(val => 29 <li className='index-ul__item' key={i++}> 30 <img src={val.picture_urls[0]} className='index-ul__image' /> 31 <h3>{val.title}</h3> 32 <p className='index-ul-icons'> 33 {val.description} 34 </p> 35 </li > 36 ) 37 38 console.log(contents); 39 40 return ( 41 <> 42 <HeaderComponent props={this.props} /> 43 <ul>{contents}</ul> 44 <FooterComponent /> 45 </> 46 ) 47 } 48} 49 50export default Home;
/sagas/index.js
javascript
1// import Axios from "axios" 2import { call, put, takeLatest, takeEvery } from 'redux-saga/effects' 3import * as Api from '../helpers/api' 4import * as F2 from '../helpers/functions' 5 6function* getTrips(action) { 7 8 let tempTrips = yield call(Api.fetch) 9 10 const trips = F2.tripTranslate(tempTrips, action.payload.lng) 11 // ここでconsole.logすると翻訳済みの本文が確認できる 12 13 yield put({ type: "GET_TRIPS_SUCCESS", trips: trips }) 14} 15 16// INDEX Action が送出されるたびにfunctionを起動 17function* rootSaga() { 18 yield takeEvery("GET_TRIPS", getTrips) 19 //アクションタイプgettypeが実行された時はredux-sagaで検知して、経由 20} 21 22export default rootSaga;
/reducers/indexReducer.js
javascript
1const initialState = { 2 trips: [], 3 lng: 'jp', 4 source: '', 5} 6// Reducer処理 7export const indexReducer = (state = initialState, action) => { 8 switch (action.type) { 9 case 'GET_TRIPS_SUCCESS': { 10 return Object.assign({}, state, { 'trips': action.trips }) 11 } 12 case 'LANG_CHANGE': { 13 return Object.assign({}, state, action.payload) 14 } 15 case 'MARKDOWN': { 16 return Object.assign({}, state, action.payload) 17 } 18 default: { 19 return state 20 } 21 } 22}
/helpers/functions.js
javascript
1// google翻訳は jpではなく、 jaで指定する必要があるので注意!! 2// use a callback function to setState 3export function tripTranslate(array, lng) { 4 if (lng === 'jp') { lng = 'ja' } 5 console.log('functionsの言語:' + lng); 6 7 array.forEach((element, i) => { 8 googleTranslate.translate(element.title, lng, function (err, translation) { 9 array[i].title = translation.translatedText 10 }); 11 googleTranslate.translate(element.description, lng, function (err, translation) { 12 array[i].description = translation.translatedText 13 }); 14 googleTranslate.translate(element.notes, lng, function (err, translation) { 15 array[i].notes = translation.notes 16 }); 17 }); 18 return array 19}
試したこと
問題の切り分けとして、別のstateを更新(GIFは言語設定のstateを jp → enに変更したらなぜか日本語になります)
*クリックしているボタンは言語設定のstateを更新するボタンです。
これくらいしかヒントがなく申し訳ありません。
何らかのstate更新タイミングの問題のような気がしていますが、はっきりしないので、何かお気づきの点があれば教えていただけると助かります。よろしくお願いいたします。
補足情報(FW/ツールのバージョンなど)
node.js : 12.0.4
react: 16.8
redux : 7.1.3
"google-translate": "^3.0.0",
回答1件
あなたの回答
tips
プレビュー