我们使用 Redux 主要有两个原因。
1- 在组件之间传递数据。
如果你不使用redux,那么你需要做prop钻孔。为了决定用户是否登录,我们获取数据,然后将其存储在 redux 存储中,然后 Header 组件连接到存储并获取身份验证信息。如果你不使用redux,那么你需要在每个页面中获取用户,然后将其传递给Header组件。
Next.js 预渲染每个页面。这意味着 Next.js 会提前为每个页面生成 HTML,而不是全部由客户端 JavaScript 完成。预渲染可以带来更好的性能和 SEO。 next-redux-wrapper 包允许您使用带有自动静态优化的 redux。如果您单击该链接,则会有一条注释说:“Next.js 在使用类 MyApp 时提供通用 getInitialProps,这将被包装器拾取,因此您不能扩展 App,因为您将选择退出自动静态优化:”。我为我的项目设置了这个包,它很容易设置。
但是使用 redux 的缺点是没有缓存。您存储数据,然后定期重新获取它以确保它是最新的。这是一项额外昂贵的工作。为了在 redux 中实现缓存,我们使用reselect 库。这意味着你的项目对 redux 的额外依赖,会让你写更多的代码。
有一个很好的包swr,它是由 next.js 创建的。 Stale-While-Revalidate。它首先从缓存(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;
}
}
);
2- 发出 api 请求。
我为我的项目设置了 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 }];
}
一个简单的apiCall函数
const createBlog = (data) => axios.post("/api/v1/blogs", data);
然后我们就是这样使用它的:
export const useCreateBlog = () => useApiHandler(createBlog);
设置 redux 很容易,因为人们很容易不用担心应用程序的性能,他们只需设置即可。在我看来,如果你有一个大型应用程序,你需要设置 redux,或者如果你熟悉 graphql,你可以使用 Apollo。这是一篇很好的文章,可以了解如何使用 apollo 作为状态管理。 apollo as state management。我建立了一个大型电子商务网站,并在我的新应用中使用了 redux,因为它相对较小,我不使用 next js 并使其更复杂。