Jam*_*e S 69 redux react-redux next.js
我正在构建一个 Next.js 应用程序,它目前正在使用 Redux。在我构建它时,我想知道是否真的有必要使用 Redux,它的使用是否实际上是一种反模式。这是我的推理:
为了在 Next.js 中正确初始化 Redux Store,您必须App使用getInitialProps方法创建自定义组件。通过这样做,您将禁用Next.js 提供的自动静态优化。
相比之下,如果我要在客户端包含 Redux,则只有在 App 挂载后,Redux 商店才会在每次服务器端导航后重置。例如,我有一个 Next.js 应用程序,它在客户端初始化 Redux 存储,但是当路由到动态路由(例如 )时pages/projects/[id],页面是服务器端呈现的,我必须重新获取店铺。
我的问题是:
App组件中初始化商店并放弃自动静态优化吗?getStaticProps和其他数据获取方法ElD*_*n90 49
如果您有一个带有 getInitialProps 的自定义应用程序,那么 Next.js 提供的自动静态优化将对所有页面禁用。
没错,如果您遵循这种方法。
有没有更好的办法 ?
是的,您可以创建一个 Redux Provider 作为包装器并包装您需要的组件,redux 上下文将自动初始化并在该组件中提供。
例子:
const IndexPage = () => {
// Implementation
const dispatch = useDispatch()
// ...
// ...
return <Something />;
}
IndexPage.getInitialProps = ({ reduxStore }) => {
// Implementation
const { dispatch } = reduxStore;
// ...
// ...
}
export default withRedux(IndexPage)
Run Code Online (Sandbox Code Playgroud)
您现在可以仅将 Redux 用于需要状态管理的页面,而无需禁用整个应用程序的优化。
回答你的问题“在 Next.js 中使用 Redux 是一种反模式吗? ”
不会,但需要正确使用。
有关如何在此处完成的更多信息:https : //github.com/vercel/next.js/tree/canary/examples/with-redux
我希望这有帮助
Yil*_*maz 14
我们使用 Redux 主要有两个原因。
如果你不使用 redux,那么你需要做 prop 钻孔。为了决定用户是否登录,我们获取数据,然后将其存储在 redux 存储中,然后 Header 组件连接到存储并获取身份验证信息。如果你没有使用redux,那么你需要在每个页面中获取用户,然后将其传递给Header组件。
Next.js 预渲染每个页面。这意味着 Next.js 会提前为每个页面生成 HTML,而不是全部由客户端 JavaScript 完成。预渲染可以带来更好的性能和 SEO。next-redux-wrapper包允许你使用带有自动静态优化的 redux。如果你点击链接,有一个注释说:“Next.js 在使用类 MyApp 时提供通用的 getInitialProps 扩展 App,它将被包装器拾取,所以你不能扩展 App,因为你会选择退出自动静态优化:”。我为我的项目设置了这个包,它很容易设置。
但是使用 redux 的缺点是它不是缓存。您存储数据,然后定期重新获取它以确保它是最新的。这是一项额外昂贵的工作。为了在 redux 中实现缓存,我们使用reselect库。这意味着你的项目在 redux 之上有额外的依赖,并且会让你编写更多的代码。
有一个很好的包swr它是由 next.js 创建的。Stale-While-Revalidate。它首先从缓存(陈旧)返回数据,然后发送获取请求,最后再次携带更新的数据。我在每个页面中选择使用这个。
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 };
};
Run Code Online (Sandbox Code Playgroud)
这是可重用的 fetcher
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;
}
}
);
Run Code Online (Sandbox Code Playgroud)
我为我的项目设置了 redux 存储,它与我设置的文本编辑器冲突。Redux 以某种方式阻止了编辑器,我无法用我在编辑器上写的文本填充商店。所以我使用可重用的钩子来获取 api。一开始看起来很亲切,但如果你分析它,就会有道理。
export function useApiHandler(apiCall) {
// fetching might have one those 3 states. you get error, you fetch the data, and you start with the loading state
const [reqState, setReqState] = useState({
error:null,
data:null,
loading:true, // initially we are loading
});
const handler = async (...data) => {
setReqState({ error: null, data: null, loading: true });
try {
// apiCall is a separate function to fetch the data
const res = await apiCall(...data);
setReqState({ error: null, data: res.data, loading: false });
alert(res.data);// just to check it
return res.data;
} catch (e) {
// short circuting in or. if first expression is true, we dont evaluate the second.
// short circuting in and. if first expression is true, result is the second expression
const message =
(e.response && e.response.data) || "Ooops, something went wrong...";
setReqState({ error: message, data: null, loading: false });
return Promise.reject(message);
}
};
return [handler, { ...reqState }];
}
Run Code Online (Sandbox Code Playgroud)
一个简单的 apiCall 函数
const createBlog = (data) => axios.post("/api/v1/blogs", data);
Run Code Online (Sandbox Code Playgroud)
然后这就是我们如何使用它:
export const useCreateBlog = () => useApiHandler(createBlog);
Run Code Online (Sandbox Code Playgroud)
设置 redux 很容易,因为人们很容易不担心他们的应用程序的性能,他们只是设置它。在我看来,如果您有一个大型应用程序,您需要设置 redux,或者如果您熟悉 graphql,您可以使用 Apollo。这是一篇很好的文章,可以了解如何使用 apollo 作为状态管理。阿波罗作为国家管理。我建立了一个大型电子商务网站,并在我的新应用程序中使用了 redux,因为它相对较小,因此我不使用 next js,使其变得更复杂。
| 归档时间: |
|
| 查看次数: |
35918 次 |
| 最近记录: |