我如何在nextjs中调度存储并覆盖初始道具

时间:2019-03-27 10:15:28

标签: reactjs redux redux-thunk next.js

我想在getInitialProps内调用API,然后将该响应保存在redux存储区中。那么我该如何调用调度存储区并覆盖初始道具

现在从API提取数据后,我可以将值分配给reducer,它还可以将数据保存在商店中,但是在保存数据后,我的应用需要初始道具(我不知道它从何处更改状态),并将我保存的新数据覆盖为初始属性。

main.js

class StepThree extends React.Component {
static async getInitialProps({ reduxStore, req }) {
    let encID = req.query.id //null
    try {
        let encode = await encrption(encID,7,'dec')
        const apiCall = await fetch(`${config.leadSearchApi}&search_param=${encode}`);
        let res = await apiCall.json();
        if(res.data['next_action'] !== "converted"){
            let test = await reduxStore.dispatch({ type: PATIENT_NAME,payload:res.data.name });
            console.log(test,'res');
            await reduxStore.dispatch({ type: PATIENT_NUMBER,payload:res.data['mobile_number'] });
            await reduxStore.dispatch({ type: LEAD_ID,payload:res.data.id });
        }

        } catch (err) {
        console.log(err,'get err');
        }
    return {  }
}

render() {
    return <div>Hello World </div>
}
}

const mapStateToProps = (state, prevProps) =>{
return{
    AmbSelect:state.StepThreeReducer.isAmbSel,
    Addons:state.StepThreeReducer.addonSel,
    VehcileData:state.StepThreeReducer.vehcileData,
    TotalPrice:state.StepThreeReducer.totalPrice,
    Cameback:state.StepThreeReducer.comeback,
    LeadID:state.Main.LeadId
}
}
export default connect(mapStateToProps,{addOnSelected,priceCal,updateLeadS3,previous,VehicleDataHandler,updateVehData, addonsCount,totalPrice,existLeadData,linkLead2,linkLead3,encrption })(StepThree);

App.js

import App, { Container } from 'next/app'
import React from 'react'
import withReduxStore from '../lib/with-redux-store'
import { Provider } from 'react-redux'
class MyApp extends App {
render () {
    const { Component, pageProps, reduxStore } = this.props;


    return (
    <Container>
        <Provider store={reduxStore}>
        <Component {...pageProps} />
        </Provider>
    </Container>
    )
}
}

export default withReduxStore(MyApp)

redux-store.js

  import React from 'react'
import { initializeStore } from '../store'

const isServer = typeof window === 'undefined'
const __NEXT_REDUX_STORE__ = '__NEXT_REDUX_STORE__'

function getOrCreateStore (initialState) {
// Always make a new store if server, otherwise state is shared between requests
if (isServer) {
    return initializeStore(initialState)
}

// Create store if unavailable on the client and set it on the window object
if (!window[__NEXT_REDUX_STORE__]) {
    window[__NEXT_REDUX_STORE__] = initializeStore(initialState)
}
return window[__NEXT_REDUX_STORE__]
}

export default App => {
return class AppWithRedux extends React.Component {
    static async getInitialProps (appContext) {
    // Get or Create the store with `undefined` as initialState
    // This allows you to set a custom default initialState
    const reduxStore = getOrCreateStore()

    // Provide the store to getInitialProps of pages
    appContext.ctx.reduxStore = reduxStore

    let appProps = {}
    if (typeof App.getInitialProps === 'function') {
        appProps = await App.getInitialProps(appContext)
    }

    return {
        ...appProps,
        initialReduxState: reduxStore.getState()
    }
    }

    constructor (props) {
    super(props)
    this.reduxStore = getOrCreateStore(props.initialReduxState)
    }

    render () {
    return <App {...this.props} reduxStore={this.reduxStore} />
    }
}
}

store.js

import { createStore, applyMiddleware,combineReducers } from 'redux'
import { composeWithDevTools } from 'redux-devtools-extension'
import thunkMiddleware from 'redux-thunk'

import './actions';
import reducer from './reducers'

export function initializeStore () {
return createStore(
    reducer,
    composeWithDevTools(applyMiddleware(thunkMiddleware))
)
}

reducer.js

import {PATIENT_NAME,PATIENT_NUMBER,RIDE_DATE,RIDE_TIME,FCAUSES,SETCAUSE} from '../actions/types';
const INITIAL_STATE = {
    patient_name:'',
    patient_number:'',
    ride_date:false,
    ride_time:false,
    causes:{},
    sel_cause:''
};
export default  (state=INITIAL_STATE,action) => {
    console.log(action,'reducer')
    switch(action.type) {
        case PATIENT_NAME:
            return {...state,patient_name:action.payload};
        case PATIENT_NUMBER:
            return {...state,patient_number:action.payload};
        case RIDE_DATE:
            return {...state,ride_date:action.payload};
        case RIDE_TIME:
            return {...state,ride_time:action.payload};
        case FCAUSES:
            return {...state,causes:action.payload};
        case SETCAUSE:
            return {...state,sel_cause:action.payload};
        default:
            return state;
    }
}

enter image description here

调度后,我不想将应用程序状态设置为初始道具
请帮忙,stuckkkkkk

1 个答案:

答案 0 :(得分:1)

创建商店时,没有在initializeStore中提供initialState。 为确保您在服务器和客户端上使用相同的状态形状,请将initialState参数传递给您将初始化存储在store.js内:

export function initializeStore(initialState = {}) {
return createStore(
    reducer,
    initialState,
    composeWithDevTools(applyMiddleware(thunkMiddleware))
  )
}

否则,将始终应用相同的状态,并且服务器传播的状态将丢失。