TypeError:将中间件添加到Redux时,getState不是函数

时间:2016-08-19 21:15:33

标签: javascript reactjs redux middleware

在我的configureStore.dev.js文件中使用此代码,我在添加import {createStore, compose, applyMiddleware} from 'redux'; import rootReducer from '../reducers'; import reduxImmutableStateInvariant from 'redux-immutable-state-invariant'; export default function configureStore(initialState) { const store = createStore(rootReducer, initialState, compose( // Add other middleware on this line... applyMiddleware(reduxImmutableStateInvariant), window.devToolsExtension ? window.devToolsExtension() : f => f // add support for Redux dev tools ) ); if (module.hot) { // Enable Webpack hot module replacement for reducers module.hot.accept('../reducers', () => { const nextReducer = require('../reducers').default; // eslint-disable-line global-require store.replaceReducer(nextReducer); }); } return store; } 时收到$ cat t1241.cu #include <cufft.h> #include <stdexcept> #include <iostream> #include <numeric> #include <vector> #define ck(cmd) if ( cmd) { std::cerr << "error at line " << __LINE__ << std::endl;exit(1);} __global__ void fill_input(cufftComplex * buf, int batch,int nbins,int stride,int seed) { for (int i = blockDim.y * blockIdx.y + threadIdx.y; i< batch;i += gridDim.y*blockDim.y) for (int j = blockDim.x * blockIdx.x + threadIdx.x; j< nbins;j += gridDim.x*blockDim.x) buf[i*stride + j] = make_cuFloatComplex( (i+seed)%101 - 50,(j+seed)%41-20); } __global__ void check_output(const float * buf1,const float * buf2,int batch, int nfft, int stride, int * errors) { for (int i = blockDim.y * blockIdx.y + threadIdx.y; i< batch;i += gridDim.y*blockDim.y) { for (int j = blockDim.x * blockIdx.x + threadIdx.x; j< nfft;j += gridDim.x*blockDim.x) { float e=buf1[i*stride+j] - buf2[i*stride+j]; if (e*e > 1) // gross error atomicAdd(errors,1); } } } void demo(bool reuse_plan) { if (reuse_plan) std::cout << "Reusing the same fft plan with multiple stream via cufftSetStream ... "; else std::cout << "Giving each stream its own dedicated fft plan ... "; int nfft = 1024; int batch = 1024; int nstreams = 8; int nbins = nfft/2+1; int nit=100; size_t inpitch,outpitch; std::vector<cufftComplex*> inbufs(nstreams); std::vector<float*> outbufs(nstreams); std::vector<float*> checkbufs(nstreams); std::vector<cudaStream_t> streams(nstreams); std::vector<cufftHandle> plans(nstreams); // if plan reuse, set up independent work areas std::vector<char *> wk_areas(nstreams); for (int i=0;i<nstreams;++i) { ck( cudaStreamCreate(&streams[i])); ck( cudaMallocPitch((void**)&inbufs[i],&inpitch,nbins*sizeof(cufftComplex),batch) ); ck( cudaMallocPitch((void**)&outbufs[i],&outpitch,nfft*sizeof(float),batch)); ck( cudaMallocPitch((void**)&checkbufs[i],&outpitch,nfft*sizeof(float),batch) ); if (i==0 || reuse_plan==false) ck ( cufftPlanMany(&plans[i],1,&nfft,&nbins,1,inpitch/sizeof(cufftComplex),&nfft,1,outpitch/sizeof(float),CUFFT_C2R,batch) ); } if (reuse_plan){ size_t ws; ck(cufftGetSize(plans[0], &ws)); for (int i = 0; i < nstreams; i++) ck(cudaMalloc(&(wk_areas[i]), ws)); ck(cufftSetAutoAllocation(plans[0], 0)); ck(cufftSetWorkArea(plans[0], wk_areas[0])); } // fill the input buffers and FFT them to get a baseline for comparison for (int i=0;i<nstreams;++i) { fill_input<<<20,dim3(32,32)>>>(inbufs[i],batch,nbins,inpitch/sizeof(cufftComplex),i); ck (cudaGetLastError()); if (reuse_plan) { ck (cufftExecC2R(plans[0],inbufs[i],checkbufs[i])); }else{ ck (cufftExecC2R(plans[i],inbufs[i],checkbufs[i])); ck( cufftSetStream(plans[i],streams[i]) ); // only need to set the stream once } ck( cudaDeviceSynchronize()); } // allocate a buffer for the error count int * errors; cudaMallocHost((void**)&errors,sizeof(int)*nit); memset(errors,0,sizeof(int)*nit); // perform the FFTs and check the outputs on streams for (int it=0;it<nit;++it) { int k = it % nstreams; ck( cudaStreamSynchronize(streams[k]) ); // make sure any prior kernels have completed if (reuse_plan) { ck(cufftSetStream(plans[0],streams[k])); ck(cufftSetWorkArea(plans[0], wk_areas[k])); // update work area pointer in plan ck(cufftExecC2R(plans[0],inbufs[k],outbufs[k])); }else{ ck(cufftExecC2R(plans[k],inbufs[k],outbufs[k])); } check_output<<<100,dim3(32,32),0,streams[k]>>>(outbufs[k],checkbufs[k],batch,nfft,outpitch/sizeof(float),&errors[it]); ck (cudaGetLastError()); } ck(cudaDeviceSynchronize()); // report number of errors int errcount=0; for (int it=0;it<nit;++it) if (errors[it]) ++errcount; std::cout << errcount << " of " << nit << " transforms had errors\n"; for (int i=0;i<nstreams;++i) { cudaFree(inbufs[i]); cudaFree(outbufs[i]); cudaFree(wk_areas[i]); cudaStreamDestroy(streams[i]); if (i==0 || reuse_plan==false) cufftDestroy(plans[i]); } } int main(int argc,char ** argv) { demo(false); demo(true); return 0; } $ nvcc -o t1241 t1241.cu -lcufft $ ./t1241 Giving each stream its own dedicated fft plan ... 0 of 100 transforms had errors Reusing the same fft plan with multiple stream via cufftSetStream ... 0 of 100 transforms had errors $ 。当我删除这个添加的中间件时,我的项目运行正常。添加此中间件的正确方法是什么?这是完整的文件:

<div class="demo-container">
    <div id="placeholder" class="demo-placeholder" style="width:800px; height:500px;"></div>
</div>

1 个答案:

答案 0 :(得分:14)

reduxImmutableStateInvariant 是在将其传递给applyMiddleware之前需要调用的函数。

SELECT
   l.id,
   l.user_id,
   l.latitude,
   l.longitude
FROM
   Location l
      LEFT JOIN Task t
         ON l.user_id = t.user_id
WHERE
      t.id IS NULL  /* No record in tasks table */
  OR (t.id IS NOT NULL AND l.status = 1) /* if records exists then all of them must have status equals to 1 */

文档在哪里?

在github README docs中,在导入(通过require)const store = createStore(rootReducer, initialState, compose( // Add other middleware on this line... applyMiddleware(reduxImmutableStateInvariant()), window.devToolsExtension ? window.devToolsExtension() : f => f // add support for Redux dev tools ) ); 后调用。见下面的第三行:

reduxImmutableStateInvariant

为什么thunk不是函数?

在thunk中间件中,thunk函数为called before it is returned

// Be sure to ONLY add this middleware in development!
const middleware = process.env.NODE_ENV !== 'production' ?
  [require('redux-immutable-state-invariant')(), thunk] :
  [thunk];

// Note passing middleware as the last argument to createStore requires redux@>=3.1.0
const store = createStore(
  reducer,
  applyMiddleware(...middleware)
);

那么为什么redux-immutable-state-invariant是一个函数?

基于代码,看起来您可以传入一个函数(const thunk = createThunkMiddleware(); thunk.withExtraArgument = createThunkMiddleware; export default thunk; ),该函数用于确定redux状态中哪些属性是不可变的。我认为提供自己的isImmutable函数是允许这个中间件与其他不可变库很好地协同工作的。

isImmutable

此处使用该方法 https://github.com/leoasis/redux-immutable-state-invariant/blob/5ed542246e32b7eec06879b25e5a0a478daf4892/src/trackForMutations.js#L5