简体   繁体   English

将 react redux 与 next.js 结合使用

[英]Using react redux with next.js

I try to use Redux with next.js starter project and I installed next-redux-wrapper on the project but I'm not sure where is the root file in this project.我尝试将 Redux 与next.js 启动项目一起使用,并且我在该项目上安装了next-redux-wrapper但我不确定该项目中的根文件在哪里。

I try to follow the tutorial shown on the next-redux-wrapper but had no success.我尝试按照next-redux-wrapper上显示的教程进行操作,但没有成功。 Nothing change.没变化。

Please help me with how to add Redux to the project.请帮助我如何将 Redux 添加到项目中。

Regards.问候。

Next.js uses the App component to initialize pages. Next.js 使用 App 组件来初始化页面。 You can override it and control the page initialization.您可以覆盖它并控制页面初始化。

Although this demo is for next.js it should work for nextjs-starter.虽然这个演示是针对 next.js 的,但它应该适用于 nextjs-starter。

install next-redux-wrapper:安装 next-redux-wrapper:

npm install --save next-redux-wrapper

Add _app.js file to ./pages directory:_app.js文件添加到./pages目录:

// pages/_app.js
import React from "react";
import {createStore} from "redux";
import {Provider} from "react-redux";
import App, {Container} from "next/app";
import withRedux from "next-redux-wrapper";

const reducer = (state = {foo: ''}, action) => {
    switch (action.type) {
        case 'FOO':
            return {...state, foo: action.payload};
        default:
            return state
    }
};

/**
* @param {object} initialState
* @param {boolean} options.isServer indicates whether it is a server side or client side
* @param {Request} options.req NodeJS Request object (not set when client applies initialState from server)
* @param {Request} options.res NodeJS Request object (not set when client applies initialState from server)
* @param {boolean} options.debug User-defined debug mode param
* @param {string} options.storeKey This key will be used to preserve store in global namespace for safe HMR 
*/
const makeStore = (initialState, options) => {
    return createStore(reducer, initialState);
};

class MyApp extends App {

    static async getInitialProps({Component, ctx}) {

        // we can dispatch from here too
        ctx.store.dispatch({type: 'FOO', payload: 'foo'});

        const pageProps = Component.getInitialProps ? await Component.getInitialProps(ctx) : {};

        return {pageProps};

    }

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

}

export default withRedux(makeStore)(MyApp);

And then, actual page components can be simply connected: This demo how to connect index.js in pages.然后,可以简单地连接实际的页面组件:这个演示如何在页面中连接index.js

import Link from "next/link";
import React from "react";
import {
  Container,
  Row,
  Col,
  Button,
  Jumbotron,
  ListGroup,
  ListGroupItem
} from "reactstrap";
import Page from "../components/page";
import Layout from "../components/layout";

import { connect } from "react-redux";

class Default extends Page {
  static getInitialProps({ store, isServer, pathname, query }) {
    store.dispatch({ type: "FOO", payload: "foo" }); // component will be able to read from store's state when rendered
    return { custom: "custom" }; // you can pass some custom props to component from here
  }
  render() {
    return (
      <Layout>content...</Layout>
    );
  }
}

export default connect()(Default);

Refer to the documentation for more information: next-redux-wrapper有关详细信息,请参阅文档: next-redux-wrapper

First i created simple next.js app with "npx create-next-app"首先,我使用“npx create-next-app”创建了简单的 next.js 应用程序

Then I created general redux setup in a folder called "store".然后我在一个名为“store”的文件夹中创建了通用的 redux 设置。

This is the folder structure这是文件夹结构在此处输入图像描述

And in pages i have created an _app.js.在页面中我创建了一个 _app.js。 Code inside it is like this-里面的代码是这样的—— 在此处输入图像描述

Please let me know if anyone needs any help with setup...如果有人需要任何设置帮助,请告诉我...

this question needs update:这个问题需要更新:

"next": "12.1.4",
"next-redux-wrapper": "^7.0.5",
"redux-devtools-extension": "^2.13.9",
"redux-thunk": "^2.4.1"

Create Store创建商店

import { createStore, applyMiddleware } from "redux";
import { HYDRATE, createWrapper } from "next-redux-wrapper";
import reducers from "./reducers/reducers";

import thunkMiddleware from "redux-thunk";

// middleware is an array
const bindMiddleware = (middleware) => {
  if (process.env.NODE_ENV !== "production") {
    const { composeWithDevTools } = require("redux-devtools-extension");
    return composeWithDevTools(applyMiddleware(...middleware));
  }
  return applyMiddleware(...middleware);
};
// this is main reducer to handle the hydration
const reducer = (state, action) => {
  // hydration is a process of filling an object with some data
  // this is called when server side request happens
  if (action.type === HYDRATE) {
    const nextState = {
      ...state,
      ...action.payload,
    };
    return nextState;
  } else {
    // whenever we deal with static rendering or client side rendering, this will be the case
    // reducers is the combinedReducers
    return reducers(state, action);
  }
};

const initStore = () => {
  return createStore(reducer, bindMiddleware([thunkMiddleware]));
};

export const wrapper = createWrapper(initStore);

_app.js _app.js

import { wrapper } from "../redux/store";

function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />;
}

export default wrapper.withRedux(MyApp);

Using it with getServerSideProps与 getServerSideProps 一起使用

// sample action
import { getRooms } from "../redux/actions/roomActions";
import { wrapper } from "../redux/store";

export const getServerSideProps = wrapper.getServerSideProps(
  (store) =>
    // destructuring context obj
    async ({ req, query }) => {
      await store.dispatch(getRooms(req, query.page));
    }
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM