将Redux与Next.js一起使用是一种反模式吗?
我正在构建一个Next.js应用程序,它目前正在使用Redux。在构建它的过程中,我想知道是否真的需要使用Redux,以及它的使用是否实际上是一种反模式。我的理由如下: 为了在Next.js中正确初始化Redux存储,您必须使用将Redux与Next.js一起使用是一种反模式吗?,redux,react-redux,next.js,Redux,React Redux,Next.js,我正在构建一个Next.js应用程序,它目前正在使用Redux。在构建它的过程中,我想知道是否真的需要使用Redux,以及它的使用是否实际上是一种反模式。我的理由如下: 为了在Next.js中正确初始化Redux存储,您必须使用getInitialProps方法创建一个自定义App组件。通过这样做,您将禁用Next.js提供的 相比之下,如果我只在安装应用程序后才在客户端包含Redux,那么每次服务器端导航后,Redux存储都会重置。例如,我有一个Next.js应用程序在客户端初始化Redux存
getInitialProps
方法创建一个自定义App
组件。通过这样做,您将禁用Next.js提供的
相比之下,如果我只在安装应用程序后才在客户端包含Redux,那么每次服务器端导航后,Redux存储都会重置。例如,我有一个Next.js应用程序在客户端初始化Redux存储,但当路由到动态路由(如pages/projects/[id]
)时,页面是服务器端呈现的,我必须重新获取存储中的任何信息
我的问题是:
App
组件中初始化存储并放弃自动静态优化getStaticProps
和const IndexPage = () => {
// Implementation
const dispatch = useDispatch()
// ...
// ...
return <Something />;
}
IndexPage.getInitialProps = ({ reduxStore }) => {
// Implementation
const { dispatch } = reduxStore;
// ...
// ...
}
export default withRedux(IndexPage)
constindexpage=()=>{
//实施
const dispatch=usedpatch()
// ...
// ...
返回;
}
IndexPage.getInitialProps=({reduxStore})=>{
//实施
const{dispatch}=reduxStore;
// ...
// ...
}
使用Redux导出默认值(IndexPage)
现在,您可以仅对需要状态管理的页面使用Redux,而不禁用整个应用程序的优化
回答您的问题“将Redux与Next.js一起使用是一种反模式吗?”
没有,但需要正确使用
有关如何操作的更多信息,请参见此处:
我希望这有帮助我们使用Redux主要有两个原因 1-在组件之间传递数据。 如果不使用redux,则需要进行支柱钻孔。为了决定用户是否登录,我们获取数据,然后将其存储在redux存储中,然后头组件连接到存储并获取身份验证信息。如果不使用redux,则需要在每个页面中获取用户,然后将其传递给Header组件 Next.js预先呈现每个页面。这意味着Next.js会提前为每个页面生成HTML,而不是由客户端JavaScript完成。预渲染可以带来更好的性能和SEO。软件包允许您将redux与自动静态优化一起使用。如果您单击该链接,会看到一条注释:“Next.js在使用类MyApp extends App时提供了通用的getInitialProps,这将由包装器拾取,因此您不能扩展应用程序,因为您将选择退出自动静态优化:”。我为我的项目设置了这个包,它很容易设置 但使用redux的缺点是,它不是缓存。存储数据,然后定期重新蚀刻以确保数据是最新的。这是一项额外昂贵的工作。为了在redux中实现缓存,我们使用库。这意味着您的项目在redux之上有额外的依赖性,这将使您编写更多的代码 有一个很好的包是由next.js创建的。重新验证时失效。它首先从缓存(stale)返回数据,然后发送获取请求,最后再次返回更新的数据。我选择在每页中使用此选项
import useSWR from "swr";
export const useGetUser = () => {
// fetcher can be any asynchronous function which returns the data. useSwr will pass "/api/v1/me" to fetcher
const { data, error, ...rest } = useSWR("/api/v1/me", fetcher);
// !data && !error if both true, loading:true, data=null=>!data=true, error=null => !error=true
return { data, error, loading: !data && !error, ...rest };
};
这是可恢复的抓取程序
export const fetcher = (url: string) =>
fetch(url).then(
async (res: Response): Promise<any> => {
const result = await res.json();
if (res.status !== 200) {
return Promise.reject(result);
} else {
return result;
}
}
);
一个简单的apiCall函数
const createBlog = (data) => axios.post("/api/v1/blogs", data);
然后这就是我们如何使用它:
export const useCreateBlog = () => useApiHandler(createBlog);
设置redux很容易,因为人们并不担心应用程序的性能,他们只是设置了redux。在我看来,如果你有一个大型应用程序,你需要设置redux,或者如果你熟悉graphql,你可以使用Apollo。这里有一篇很好的文章来了解如何使用阿波罗作为国家管理。我建立了一个大型电子商务网站,并在我的新应用程序中使用了redux,因为它相对较小,我不使用next js,使其更复杂。我个人认为使用redux在任何情况下都不是一个好主意。例如,最好使用useContext,或者在极度需要集中存储的情况下,使用mobx。但事实上,有一种简单的方法可以将Redux与SSR一起使用,而不必使用getInitialProps 这里有一点很重要——我给出的解决方案仅适用于不使用服务器上每个页面的呈现的情况——在第一次呈现之后,应用程序按照路径呈现下一个页面。在该解决方案中,假定存储将在服务器端初始化一次,然后渲染结果将传输到客户端。如果每次导航路线时都需要在服务器上呈现页面,并且需要保存存储状态,那么您最好还是查看下一个redux包装器 因此,要首先在getServerSideProps上初始化存储,您需要按如下所示更改存储初始化文件(可能会有其他导入): 之后,在需要存储在getServerSideProps中服务器端的页面中,可以简单地使用initializeStore:
import { initializeStore } from '@Redux';
// Compnent code here...
export const getServerSideProps(context: any) {
const reduxStore = initializeStore();
// reduxStore = {
// dispatch: [Function (anonymous)],
// subscribe: [Function: subscribe],
// getState: [Function: getState],
// }
// Doing something with the storage...
const initialReduxState = storeInstance.getState(); // and get it state
return { props: { initialReduxState, ...someProps } };
}
另外,不要忘记,如果您需要在_app.js中访问商店,则必须将商店定义为:
const store = initializeStore(pageProps.initialReduxState);
import { initializeStore } from '@Redux';
// Compnent code here...
export const getServerSideProps(context: any) {
const reduxStore = initializeStore();
// reduxStore = {
// dispatch: [Function (anonymous)],
// subscribe: [Function: subscribe],
// getState: [Function: getState],
// }
// Doing something with the storage...
const initialReduxState = storeInstance.getState(); // and get it state
return { props: { initialReduxState, ...someProps } };
}
const store = initializeStore(pageProps.initialReduxState);