前提・実現したいこと
React,Redux-SagaでAPIを叩く毎に、
storeのstateの配列に、配列を追加させ、
画面に表示させたいです。
- 初期レンダー
問題なく表示される
0. 再レンダーのためのAPIを叩く
レスポンスはきちんと返ってきてる
0. リデューサーでエラー
0. 再レンダーされない
※APIからのレスポンスは初期レンダー時も、再レンダー時もJSONの配列が返ってくる。
※以下の処理以外は問題なく動作をしている。
◆現在のコード
action.js
export const REQUEST_FETCH = 'REQUEST_FETCH'; export const SUCCESS_FETCH = 'SUCCESS_FETCH'; export const FAILED_FETCH = 'FAILED_FETCH'; export const REQUEST_REFETCH = 'REQUEST_REFETCH'; export const SUCCESS_REFETCH = 'SUCCESS_REFETCH'; export const FAILED_REFETCH = 'FAILED_REFETCH'; // API export const requestFetch = () => ({ type: REQUEST_FETCH, }); // API成功 export const succeedFetch = (response) => ({ type: SUCCESS_FETCH, respose, }); // APIエラー export const failedFetch = (error) => ({ type: FAILED_FETCH, error, }); // 再レンダーAPI export const requestReFetch = (results) => ({ type: REQUEST_REFETCH, }); // 再レンダーAPI成功 export const succeedReFetch = (results) => ({ type: SUCCESS_REFETCH, results, }); // 再レンダーエラー export const failedReFetch = (results) => ({ type: FAILED_REFETCH, results, });
reducer.js
import { REQUEST_FETCH, SUCCESS_FETCH, FAILED_FETCH, REQUEST_REFETCH, SUCCESS_REFETCH, FAILED_REFETCH, } from './action'; const initialState = { isFetching: true, isError: false, response: {}, }; const Reducer = (state = initialState, action) => { switch (action.type) { // API case REQUEST_FETCH: return { ...state, }; // API成功 case SUCCESS_FETCH: return { ...state, isFetching: false, isError: false, response: action.response, }; // APIエラー case FAILED_FETCH: return { ...state, isFetching: false, isError: true, response: action.error, }; // 再レンダーAPI case REQUEST_REFETCH: return { ...state, }; // 再レンダーAPI成功 case SUCCESS_REFETCH: return { ...state, isFetching: false, // *** 問題のコード *** response: [...state.response, action.results], // 以下も試しましたが、同じくエラー // response: state.response.concat(action.results), }; // 再レンダーAPIエラー case FAILED_REFETCH: return { ...state, isFetching: false, isError: true, response: action.reError, }; default: return state; } };
一応saga.jsも記載します。
import Api from './api'; import { call, put, takeEvery } from 'redux-saga/effects'; import { REQUEST_FETCH, succeedFetch, failedFetch, REQUEST_REFETCH, succeedReFetch, failedReFetch, } from './action'; // API操作 function* fetchData() { const { response, error } = yield call(Api); if (response) { yield put(succeedFetch(response)); } else { yield put(failedFetch(error)); } } // 再レンダー function* reFetchData() { const { results, reError } = yield call(Api); if (results) { yield put(succeedReFetch(results)); } else { yield put(failedReFetch(reError)); } } const mySaga = [ takeEvery(REQUEST_FETCH, fetchData), takeEvery(REQUEST_REFETCH, reFetchData), ]; export default mySaga;
理屈的にも、
記載方法としても間違っていないように見えるのですが、
以下のエラーが出てしまいます。
発生している問題・エラーメッセージ
スプレッドで記載の場合
TypeError: state.response is not iterable
concatで記載の場合
TypeError: state.response.concat is not a function
該当のソースコード
reducer.js
response: [...state.response, action.results],
response: state.response.concat(action.results),
色々書き方を変えて試してみましたが、
エラーがなくならないか、違う結果になってしまいます。
試したこと
- actionでの受け取り方を変える
export const succeedReFetch = (results) => ({ type: SUCCESS_REFETCH, response: results, });
export const succeedReFetch = (results) => ({ type: SUCCESS_REFETCH, response: [results], });
- reducerでの受け取り方を変える
case SUCCESS_REFETCH: return { ...state, response: {...state.response, action.results}, // response: state.response.concat([action.results]), };
case SUCCESS_REFETCH: return Object.assign({}, state, { response: [...state.response, action.results], });
以下は再レンダーされるが、追加ではなく、中身が丸々入れ替わってしまう。
case SUCCESS_REFETCH: return { response: action.results, });
いずれもエラーや望む結果を得る事はできませんでした。
上記ばかりを書き換えてみましたが、別の視点が考えられるでしょうか。
解決策をご教示いただけますと幸いです。
※タイポあったら申し訳ございません。
回答2件
あなたの回答
tips
プレビュー