Как отправить избыточное действие изнутри getInitialProps в Next JS? - PullRequest
0 голосов
/ 10 апреля 2020

Чтобы уточнить, я знаю, что есть схожие вопросы, но ни одно из решений не работает для меня, поэтому я решил задать этот вопрос и предоставить более подробную информацию, исходный код и то, что я пробовал до сих пор, и что, похоже, работает, но выглядит как обходной путь. Я пытаюсь отправить избыточное действие в методе getInitialProps метода Next JS, его цель - загрузить и кэшировать настройки CMS, Page info et c. Вы поняли. Я не могу заставить это работать, возможно, я что-то пропустил или я пытаюсь сделать что-то, что не должно работать в любом случае? Вот код, довольно стандартный для того, что вы будете делать, создайте метод makeStore, подключите все редукторы, определите имена ваших действий и создателей действий. Проблема в том, что диспетчер не обновляет страницу, даже если она должна (или нет?). Единственный способ, с помощью которого я нашел это, работает так:

Index.getInitialProps = async function({ store }) {
  let awaited = await store.dispatch(say("Hello World"));
  const state = store.getState();
  return {
    greeting: state.say.text
  };
}

Но это все равно не обновит компоненты, такие как заголовок, который будет содержать некоторые настройки из моего редуктора (например, если мой заголовок выведет значение say.text. Или я должен запросить данные в getInitialProps, а затем отправить действие изнутри компонента страницы, используя хук useEffect (это кажется огромным обходным решением) ?
Вот код из моего приложения, которое я получил до сих пор (все определения)
Главная страница

import { connect } from "react-redux"
import { say } from '../redux/actions/say.actions';

const Index = (props) => {
  console.log(props); // the value of greeting is "" - from the initial state even tho dispatch should update it.
  return (
    <h1>{ props.greeting }</h1>
  )
}

Index.getInitialProps = async function({ store }) {
  // store.dispatch(say("Hello World!")); // This does not update anything
  // const awaited = await store.dispatch(say("Hello World")); // This does not update anything either
  return {};
}

const mapStateToProps = state => ({
  greeting: state.say.text
});

export default connect(mapStateToProps, {})(Index);

Обертка приложения

import { makeStore } from '../redux/store';
import { Provider } from "react-redux";
import withRedux from "next-redux-wrapper";

const App = (props) => {
  const {Component, pageProps, store} = props;
  return (
    <Provider store={store}>
        <Component {...pageProps} />
    </Provider>
  );
}

App.getInitialProps = async function({Component, ctx}) {
  return {
    pageProps: {
      ...(Component.getInitialProps ? await Component.getInitialProps(ctx) : {}),
    }
  };
}

export default withRedux(makeStore)(App);

Действие

export const SAY = "SAY";

export const say = (text) => {
  return {
    type: SAY,
    text,
  }
}

Редуктор

import { SAY } from '../actions/say.actions';

const initialState = { text: "" };

const sayReducer = (state = initialState, action) => {
  switch (action.type) {
    case SAY:
      return { ...state, text: action.text };
    default:
      return state;
  }
};

export default sayReducer;

Store, makeStore

import { createStore, applyMiddleware, combineReducers } from 'redux'
import thunkMiddleware from 'redux-thunk'
import sayReducer from './reducers/say.reducer';

const bindMiddleware = middleware => {
  if (process.env.NODE_ENV !== 'production') {
    const { composeWithDevTools } = require('redux-devtools-extension')
    return composeWithDevTools(applyMiddleware(...middleware))
  }
  return applyMiddleware(...middleware)
}

export const makeStore = () => {
  return createStore(
    combineReducers({
      say: sayReducer,
    }),
    bindMiddleware([thunkMiddleware])
  )
}

Большое спасибо за помощь

...