{"id":47830,"date":"2023-07-02T02:22:42","date_gmt":"2023-01-22T13:02:02","guid":{"rendered":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8rescript-x-next-js%e7%8e%af%e5%a2%83%e4%b8%ad%e5%bc%95%e5%85%a5graphql%e5%ba%93relay%e3%80%82\/"},"modified":"2024-04-30T11:35:03","modified_gmt":"2024-04-30T03:35:03","slug":"%e5%9c%a8rescript-x-next-js%e7%8e%af%e5%a2%83%e4%b8%ad%e5%bc%95%e5%85%a5graphql%e5%ba%93relay%e3%80%82","status":"publish","type":"post","link":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8rescript-x-next-js%e7%8e%af%e5%a2%83%e4%b8%ad%e5%bc%95%e5%85%a5graphql%e5%ba%93relay%e3%80%82\/","title":{"rendered":"\u5728ReScript x Next.js\u73af\u5883\u4e2d\u5f15\u5165GraphQL\u5e93&#8221;Relay&#8221;"},"content":{"rendered":"<p>\u5728\u57fa\u4e8eNext.js\uff0cReScript\u548ctailwind\u7684\u73af\u5883\u4e2d\uff0c\u5c1d\u8bd5\u4f7f\u7528GraphQL\u8fdb\u884c\u5f00\u53d1\u3002<\/p>\n<h1>\u56fe\u7075\u5b8c\u5907\u67e5\u8be2\u8bed\u8a00<\/h1>\n<p>Facebook\u5f00\u53d1\u7684\u67e5\u8be2\u8bed\u8a00\u3002<br \/>\n\u7528\u6237\u53ef\u4ee5\u5728\u5ba2\u6237\u7aef\u6307\u5b9a\u54cd\u5e94\u683c\u5f0f\u3002<\/p>\n<p>\u5f53\u5728\u9009\u62e9\u4f7f\u7528React\u4f5c\u4e3aGraphQL\u5ba2\u6237\u7aef\u65f6\uff0c\u4e24\u4e2a\u4e3b\u8981\u7684\u9009\u62e9\u4f3c\u4e4e\u662fApollo Client\u548cRelay\u3002<br \/>\nGraphQL\u7684\u5b98\u65b9\u7f51\u7ad9\u4e0a\u8fd8\u5217\u51fa\u4e86\u670d\u52a1\u5668\u7aef\u548c\u5176\u4ed6\u5ba2\u6237\u7aef\u7684\u9009\u62e9\u3002<\/p>\n<h2>\u963f\u6ce2\u7f57\u5ba2\u6237\u7aef<\/h2>\n<p>Apollo Client<br \/>\n\u963f\u6ce2\u7f57\u5ba2\u6237\u7aef<br \/>\nRescript Apollo Client<br \/>\nRescript \u963f\u6ce2\u7f57\u5ba2\u6237\u7aef<\/p>\n<h2>\u8f6c\u53d1<\/h2>\n<p>\u8f6c\u64ad<br \/>\n\u91cd\u65b0\u4fee\u6539\u7684\u4e2d\u7ee7<\/p>\n<h1>\u5b9e\u65bd<\/h1>\n<p>\u6309\u7167RescriptRelay\u7684\u8bf4\u660e\u8fdb\u884c\u57fa\u672c\u64cd\u4f5c\u3002<\/p>\n<h2>\u589e\u52a0\u63a5\u529b<\/h2>\n<p>\u4e3a\u4e86\u5229\u7528Suspense\uff0c\u5c06React\u5e93\u8bbe\u4e3a\u5b9e\u9a8c\u7248\u672c\u3002<\/p>\n<pre class=\"post-pre\"><code>yarn add react@0.0.0-experimental-4e08fb10c react-dom@0.0.0-experimental-4e08fb10c\r\nyarn add relay-runtime@11.0.0 relay-compiler@11.0.0 react-relay@11.0.0 relay-config@11.0.0\r\nyarn add <span class=\"nt\">--dev<\/span> rescript-relay graphql reason-promise bs-fetch\r\n<\/code><\/pre>\n<h2>\u4e2d\u7ee7\u8bbe\u5b9a<\/h2>\n<h3>\u914d\u7f6e<\/h3>\n<pre class=\"post-pre\"><code><span class=\"nx\">module<\/span><span class=\"p\">.<\/span><span class=\"nx\">exports<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"na\">src<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">.\/src<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"na\">schema<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">.\/schema.graphql<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"na\">artifactDirectory<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">.\/src\/__generated__<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"na\">customScalars<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"na\">Datetime<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">string<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n        <span class=\"na\">Color<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">Color.t<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"p\">},<\/span>\r\n<span class=\"p\">};<\/span>\r\n<\/code><\/pre>\n<p>\u4e3a\u4e86\u5c06Next.js\u7684res\u6587\u4ef6\u7edf\u4e00\u653e\u7f6e\u5230\u4e00\u4e2a\u6587\u4ef6\u5939\u4e2d\uff0c\u9700\u8981\u501f\u52a9RescriptRelay\u914d\u7f6e\u6587\u4ef6\u4e2dsrc\u76ee\u5f55\u7684\u6307\u5b9a\u65b9\u6cd5\u5f71\u54cd\u5c06\u5176\u79fb\u5230src\u6587\u4ef6\u5939\u4e2d\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nb\">mv <\/span>pages components bindings src\/ \r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code>  <span class=\"nl\">\"sources\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span>\r\n<span class=\"hdl\"><span class=\"err\">-<\/span>    <span class=\"p\">{<\/span>\r\n<\/span><span class=\"hdl\"><span class=\"err\">-<\/span>      <span class=\"nl\">\"dir\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"components\"<\/span><span class=\"p\">,<\/span>\r\n<\/span><span class=\"hdl\"><span class=\"err\">-<\/span>      <span class=\"nl\">\"subdirs\"<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span>\r\n<\/span><span class=\"hdl\"><span class=\"err\">-<\/span>    <span class=\"p\">},<\/span>\r\n<\/span><span class=\"hdl\"><span class=\"err\">-<\/span>    <span class=\"p\">{<\/span>\r\n<\/span><span class=\"hdl\"><span class=\"err\">-<\/span>      <span class=\"nl\">\"dir\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"pages\"<\/span><span class=\"p\">,<\/span>\r\n<\/span><span class=\"hdl\"><span class=\"err\">-<\/span>      <span class=\"nl\">\"subdirs\"<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span>\r\n<\/span><span class=\"hdl\"><span class=\"err\">-<\/span>    <span class=\"p\">},<\/span>\r\n<\/span><span class=\"hdl\"><span class=\"err\">-<\/span>    <span class=\"p\">{<\/span>\r\n<\/span><span class=\"hdl\"><span class=\"err\">-<\/span>      <span class=\"nl\">\"dir\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"bindings\"<\/span><span class=\"p\">,<\/span>\r\n<\/span><span class=\"hdl\"><span class=\"err\">-<\/span>      <span class=\"nl\">\"subdirs\"<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span>\r\n<\/span><span class=\"hdl\"><span class=\"err\">-<\/span>    <span class=\"p\">}<\/span>\r\n<\/span><span class=\"hil\"><span class=\"err\">+<\/span>    <span class=\"p\">{<\/span>\r\n<\/span><span class=\"hil\"><span class=\"err\">+<\/span>      <span class=\"nl\">\"dir\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"src\"<\/span><span class=\"p\">,<\/span>\r\n<\/span><span class=\"hil\"><span class=\"err\">+<\/span>      <span class=\"nl\">\"subdirs\"<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span>\r\n<\/span><span class=\"hil\"><span class=\"err\">+<\/span>    <span class=\"p\">}<\/span>\r\n<\/span>  <span class=\"p\">]<\/span><span class=\"err\">,<\/span>\r\n<span class=\"hil\"><span class=\"o\">+ <\/span> <span class=\"nl\">\"ppx-flags\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span>\r\n<\/span><span class=\"hil\"><span class=\"err\">+<\/span>    <span class=\"s2\">\"rescript-relay\/ppx\"<\/span>\r\n<\/span><span class=\"hil\"><span class=\"err\">+<\/span>  <span class=\"p\">]<\/span><span class=\"err\">,<\/span>\r\n<\/span>  <span class=\"nl\">\"bs-dependencies\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span>\r\n<span class=\"hdl\"><span class=\"err\">-<\/span>    <span class=\"s2\">\"@rescript\/react\"<\/span>\r\n<\/span><span class=\"hil\"><span class=\"err\">+<\/span>    <span class=\"s2\">\"@rescript\/react\"<\/span><span class=\"p\">,<\/span>\r\n<\/span><span class=\"hil\"><span class=\"err\">+<\/span>    <span class=\"s2\">\"rescript-relay\"<\/span><span class=\"p\">,<\/span>\r\n<\/span><span class=\"hil\"><span class=\"err\">+<\/span>    <span class=\"s2\">\"reason-promise\"<\/span><span class=\"p\">,<\/span>\r\n<\/span><span class=\"hil\"><span class=\"err\">+<\/span>    <span class=\"s2\">\"bs-fetch\"<\/span>\r\n<\/span>  <span class=\"p\">]<\/span><span class=\"err\">,<\/span>\r\n<\/code><\/pre>\n<p>\u5982\u679c\u4f7f\u7528\u4e86Tailwind\uff0c\u4e5f\u9700\u8981\u66f4\u6539\u76ee\u5f55\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nx\">module<\/span><span class=\"p\">.<\/span><span class=\"nx\">exports<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"na\">purge<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span>\r\n<span class=\"hdl\"><span class=\"o\">- <\/span>       <span class=\"dl\">'<\/span><span class=\"s1\">.\/pages\/**\/*.res<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\r\n<\/span><span class=\"hdl\"><span class=\"o\">- <\/span>       <span class=\"dl\">'<\/span><span class=\"s1\">.\/components\/**\/*.res<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\r\n<\/span><span class=\"hil\"><span class=\"o\">+ <\/span>       <span class=\"dl\">'<\/span><span class=\"s1\">.\/src\/pages\/**\/*.res<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\r\n<\/span><span class=\"hil\"><span class=\"o\">+ <\/span>       <span class=\"dl\">'<\/span><span class=\"s1\">.\/src\/components\/**\/*.res<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\r\n<\/span>    <span class=\"p\">],<\/span>\r\n    <span class=\"na\">darkMode<\/span><span class=\"p\">:<\/span> <span class=\"kc\">false<\/span><span class=\"p\">,<\/span> <span class=\"c1\">\/\/ or 'media' or 'class'<\/span>\r\n    <span class=\"na\">theme<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"na\">extend<\/span><span class=\"p\">:<\/span> <span class=\"p\">{},<\/span>\r\n    <span class=\"p\">},<\/span>\r\n    <span class=\"na\">variants<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"na\">extend<\/span><span class=\"p\">:<\/span> <span class=\"p\">{},<\/span>\r\n    <span class=\"p\">},<\/span>\r\n    <span class=\"na\">plugins<\/span><span class=\"p\">:<\/span> <span class=\"p\">[],<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code>  <span class=\"nl\">\"scripts\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"nl\">\"dev\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"concurrently <\/span><span class=\"se\">\\\"<\/span><span class=\"s2\">bsb -clean-world -make-world -w<\/span><span class=\"se\">\\\"<\/span> <span class=\"se\">\\\"<\/span><span class=\"s2\">next dev<\/span><span class=\"se\">\\\"<\/span><span class=\"s2\">\"<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"nl\">\"dev:reason\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"bsb -clean-world -make-world -w\"<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"nl\">\"dev:next\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"next dev\"<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"nl\">\"build\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"bsb -clean-world -make-world &amp;&amp; next build\"<\/span><span class=\"p\">,<\/span>\r\n<span class=\"hdl\"><span class=\"err\">-<\/span>    <span class=\"nl\">\"start\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"next start\"<\/span>\r\n<\/span><span class=\"hil\"><span class=\"err\">+<\/span>    <span class=\"nl\">\"start\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"next start\"<\/span><span class=\"p\">,<\/span>\r\n<\/span><span class=\"hil\"><span class=\"err\">+<\/span>    <span class=\"nl\">\"relay\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"rescript-relay-compiler\"<\/span><span class=\"p\">,<\/span>\r\n<\/span><span class=\"hil\"><span class=\"err\">+<\/span>    <span class=\"nl\">\"relay:watch\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"rescript-relay-compiler --watch\"<\/span>\r\n<\/span>  <span class=\"p\">}<\/span><span class=\"err\">,<\/span>\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">withTM<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">require<\/span><span class=\"p\">(<\/span><span class=\"dl\">'<\/span><span class=\"s1\">next-transpile-modules<\/span><span class=\"dl\">'<\/span><span class=\"p\">)([<\/span><span class=\"dl\">'<\/span><span class=\"s1\">bs-platform<\/span><span class=\"dl\">'<\/span><span class=\"p\">])<\/span>\r\n\r\n<span class=\"nx\">module<\/span><span class=\"p\">.<\/span><span class=\"nx\">exports<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">withTM<\/span><span class=\"p\">({<\/span>\r\n<span class=\"hdl\"><span class=\"o\">- <\/span>   <span class=\"na\">pageExtensions<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span><span class=\"dl\">'<\/span><span class=\"s1\">jsx<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">js<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">bs.js<\/span><span class=\"dl\">'<\/span><span class=\"p\">]<\/span>\r\n<\/span><span class=\"hil\"><span class=\"o\">+ <\/span>   <span class=\"na\">pageExtensions<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span><span class=\"dl\">'<\/span><span class=\"s1\">jsx<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">js<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">bs.js<\/span><span class=\"dl\">'<\/span><span class=\"p\">],<\/span>\r\n<\/span><span class=\"hil\"><span class=\"o\">+ <\/span>   <span class=\"na\">experimental<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\r\n<\/span><span class=\"hil\"><span class=\"o\">+ <\/span>       <span class=\"na\">reactMode<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">concurrent<\/span><span class=\"dl\">'<\/span>\r\n<\/span><span class=\"hil\"><span class=\"o\">+ <\/span>   <span class=\"p\">}<\/span>\r\n<\/span><span class=\"p\">})<\/span>\r\n<\/code><\/pre>\n<p>\u5f00\u542f\u5b9e\u9a8c\u6027\u8bbe\u7f6e\u3002<br \/>\n\u5982\u679c\u5fd8\u8bb0\u4e86\uff0c\u4f1a\u51fa\u73b0Cannot hydrate Suspense in legacy mode\u9519\u8bef\uff0c\u6240\u4ee5\u8981\u6ce8\u610f\u3002<\/p>\n<h3>es6\u6539\u4e3acommonjs<\/h3>\n<p>\u7531\u4e8ebs-fetch\u7684\u5173\u7cfb\uff0c\u5c06bsconfig.json\u4e2d\u7684package-specs\u4ecees6\u66f4\u6539\u4e3acommonjs\u3002<\/p>\n<p>\u53c2\u8003\u306b\u3057\u306a\u304c\u3089\u3001ReasonML\u3092\u4f7f\u7528\u3057\u3066Next.js\u3067\u30da\u30fc\u30b8\u9077\u79fb\u3057\u3001Web API\u3092\u547c\u3073\u51fa\u3057\u3001\u30ec\u30b9\u30dd\u30f3\u30b9\u3092\u8868\u793a\u3057\u307e\u3059\u3002bs-fetch\u3068bs-json\u3092\u8ffd\u52a0\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code>  <span class=\"nl\">\"package-specs\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\r\n<span class=\"hdl\"><span class=\"err\">-<\/span>    <span class=\"nl\">\"module\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"es6\"<\/span><span class=\"p\">,<\/span>\r\n<\/span><span class=\"hil\"><span class=\"err\">+<\/span>    <span class=\"nl\">\"module\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"commonjs\"<\/span><span class=\"p\">,<\/span>\r\n<\/span>    <span class=\"nl\">\"in-source\"<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span>\r\n  <span class=\"p\">}<\/span><span class=\"err\">,<\/span>\r\n<\/code><\/pre>\n<h3>\u5199\u914d\u7f6e\u7ec4\u4ef6<\/h3>\n<pre class=\"post-pre\"><code><span class=\"cm\">\/* This is just a custom exception to indicate that something went wrong. *\/<\/span>\r\n<span class=\"k\">exception<\/span> <span class=\"nc\">Graphql_error<\/span><span class=\"p\">(<\/span><span class=\"kt\">string<\/span><span class=\"p\">)<\/span>\r\n\r\n<span class=\"cm\">\/**\r\n * A standard fetch that sends our operation and variables to the\r\n * GraphQL server, and then decodes and returns the response.\r\n *\/<\/span>\r\n<span class=\"k\">let<\/span> <span class=\"n\">fetchQuery<\/span>: <span class=\"nn\">RescriptRelay<\/span><span class=\"p\">.<\/span><span class=\"nn\">Network<\/span><span class=\"p\">.<\/span><span class=\"n\">fetchFunctionPromise<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span>\r\n  <span class=\"n\">operation<\/span>,\r\n  <span class=\"n\">variables<\/span>,\r\n  <span class=\"n\">_cacheConfig<\/span>,\r\n  <span class=\"n\">_uploadables<\/span>,\r\n<span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"k\">open<\/span> <span class=\"nc\">Fetch<\/span>\r\n    <span class=\"n\">fetchWithInit<\/span><span class=\"p\">(<\/span>\r\n        <span class=\"nn\">Env<\/span><span class=\"p\">.<\/span><span class=\"n\">graphQlUrl<\/span>,\r\n        <span class=\"nn\">RequestInit<\/span><span class=\"p\">.<\/span><span class=\"n\">make<\/span><span class=\"p\">(<\/span>\r\n            ~<span class=\"n\">method_<\/span><span class=\"o\">=<\/span><span class=\"nc\">Post<\/span>,\r\n            ~<span class=\"n\">body<\/span><span class=\"o\">=<\/span><span class=\"nn\">Js<\/span><span class=\"p\">.<\/span><span class=\"nn\">Dict<\/span><span class=\"p\">.<\/span><span class=\"n\">fromList<\/span><span class=\"p\">(<\/span><span class=\"kt\">list<\/span><span class=\"p\">{<\/span>\r\n                <span class=\"p\">(<\/span><span class=\"s2\">\"query\"<\/span>, <span class=\"nn\">Js<\/span><span class=\"p\">.<\/span><span class=\"nn\">Json<\/span><span class=\"p\">.<\/span><span class=\"n\">string<\/span><span class=\"p\">(<\/span><span class=\"n\">operation<\/span>.<span class=\"n\">text<\/span><span class=\"p\">))<\/span>,\r\n                <span class=\"p\">(<\/span><span class=\"s2\">\"variables\"<\/span>, <span class=\"n\">variables<\/span><span class=\"p\">)<\/span>,\r\n            <span class=\"p\">})<\/span>\r\n            <span class=\"o\">-&gt;<\/span><span class=\"nn\">Js<\/span><span class=\"p\">.<\/span><span class=\"nn\">Json<\/span><span class=\"p\">.<\/span><span class=\"n\">object_<\/span>\r\n            <span class=\"o\">-&gt;<\/span><span class=\"nn\">Js<\/span><span class=\"p\">.<\/span><span class=\"nn\">Json<\/span><span class=\"p\">.<\/span><span class=\"n\">stringify<\/span>\r\n            <span class=\"o\">-&gt;<\/span><span class=\"nn\">BodyInit<\/span><span class=\"p\">.<\/span><span class=\"n\">make<\/span>,\r\n            ~<span class=\"n\">headers<\/span><span class=\"o\">=<\/span><span class=\"nn\">HeadersInit<\/span><span class=\"p\">.<\/span><span class=\"n\">make<\/span><span class=\"p\">({<\/span>\r\n                <span class=\"s2\">\"content-type\"<\/span>: <span class=\"s2\">\"application\/json\"<\/span>,\r\n                <span class=\"s2\">\"accept\"<\/span>: <span class=\"s2\">\"application\/json\"<\/span>,\r\n<span class=\"c1\">\/\/                \"authorization\": \"Bearer \" ++ Env.graphQlToken,  \/\/ \u4eca\u56de\u306f\u8a8d\u53ef\uff08authorization\uff09\u3092\u8981\u3057\u306a\u3044\u306e\u3067\u3053\u306e\u884c\u306f\u4e0d\u8981\u3002graphCMS\u7b49\u7528\u3044\u308b\u5834\u5408\u8a18\u8ff0\u3059\u308b\u3002<\/span>\r\n            <span class=\"p\">})<\/span>,\r\n            <span class=\"p\">()<\/span>,\r\n        <span class=\"p\">)<\/span>,\r\n    <span class=\"p\">)<\/span> <span class=\"o\">|&gt;<\/span> <span class=\"nn\">Js<\/span><span class=\"p\">.<\/span><span class=\"nn\">Promise<\/span><span class=\"p\">.<\/span><span class=\"n\">then_<\/span><span class=\"p\">(<\/span><span class=\"n\">resp<\/span> <span class=\"o\">=&gt;<\/span>\r\n        <span class=\"k\">if<\/span> <span class=\"nn\">Response<\/span><span class=\"p\">.<\/span><span class=\"n\">ok<\/span><span class=\"p\">(<\/span><span class=\"n\">resp<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n            <span class=\"nn\">Response<\/span><span class=\"p\">.<\/span><span class=\"n\">json<\/span><span class=\"p\">(<\/span><span class=\"n\">resp<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"p\">{<\/span>\r\n            <span class=\"nn\">Js<\/span><span class=\"p\">.<\/span><span class=\"nn\">Promise<\/span><span class=\"p\">.<\/span><span class=\"n\">reject<\/span><span class=\"p\">(<\/span><span class=\"nc\">Graphql_error<\/span><span class=\"p\">(<\/span><span class=\"s2\">\"Request failed: \"<\/span> <span class=\"o\">++<\/span> <span class=\"nn\">Response<\/span><span class=\"p\">.<\/span><span class=\"n\">statusText<\/span><span class=\"p\">(<\/span><span class=\"n\">resp<\/span><span class=\"p\">)))<\/span>\r\n        <span class=\"p\">}<\/span>\r\n    <span class=\"p\">)<\/span>\r\n<span class=\"p\">}<\/span>\r\n\r\n<span class=\"k\">let<\/span> <span class=\"n\">network<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">RescriptRelay<\/span><span class=\"p\">.<\/span><span class=\"nn\">Network<\/span><span class=\"p\">.<\/span><span class=\"n\">makePromiseBased<\/span><span class=\"p\">(<\/span>~<span class=\"n\">fetchFunction<\/span><span class=\"o\">=<\/span><span class=\"n\">fetchQuery<\/span>, <span class=\"p\">())<\/span>\r\n\r\n<span class=\"k\">let<\/span> <span class=\"n\">environment<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">RescriptRelay<\/span><span class=\"p\">.<\/span><span class=\"nn\">Environment<\/span><span class=\"p\">.<\/span><span class=\"n\">make<\/span><span class=\"p\">(<\/span>\r\n        ~<span class=\"n\">network<\/span>,\r\n        ~<span class=\"n\">store<\/span><span class=\"o\">=<\/span><span class=\"nn\">RescriptRelay<\/span><span class=\"p\">.<\/span><span class=\"nn\">Store<\/span><span class=\"p\">.<\/span><span class=\"n\">make<\/span><span class=\"p\">(<\/span>\r\n        ~<span class=\"n\">source<\/span><span class=\"o\">=<\/span><span class=\"nn\">RescriptRelay<\/span><span class=\"p\">.<\/span><span class=\"nn\">RecordSource<\/span><span class=\"p\">.<\/span><span class=\"n\">make<\/span><span class=\"p\">()<\/span>,\r\n        ~<span class=\"n\">gcReleaseBufferSize<\/span><span class=\"o\">=<\/span><span class=\"mi\">10<\/span>, <span class=\"cm\">\/* This sets the query cache size to 10 *\/<\/span>\r\n        <span class=\"p\">()<\/span>,\r\n    <span class=\"p\">)<\/span>,\r\n    <span class=\"p\">()<\/span>,\r\n<span class=\"p\">)<\/span>\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code><span class=\"c1\">\/\/ api<\/span>\r\n<span class=\"nd\">@val<\/span> <span class=\"k\">external<\/span> <span class=\"n\">graphQlUrl<\/span>:<span class=\"kt\">string<\/span> <span class=\"o\">=<\/span> <span class=\"s2\">\"process.env.NEXT_PUBLIC_GRAPHQL_URL\"<\/span>\r\n<span class=\"c1\">\/\/ @val external graphQlToken:string = \"process.env.NEXT_PUBLIC_GRAPHQL_TOKEN\"  \/\/ authorization\u304c\u5fc5\u8981\u306a\u5834\u5408<\/span>\r\n<\/code><\/pre>\n<p>\u5728\u4f7f\u7528Next.js\u65f6\uff0c\u5982\u679c\u8981\u5728\u6d4f\u89c8\u5668\u4e2d\u4f7f\u7528\u73af\u5883\u53d8\u91cf\uff0c\u5219\u9700\u8981\u5728\u5f00\u5934\u52a0\u4e0aNEXT_PUBLIC_\u524d\u7f00\u3002<\/p>\n<pre class=\"post-pre\"><code>NEXT_PUBLIC_GRAPHQL_URL=\"&lt;YOUR_GRAPHQL_API_URL&gt;\"\r\n# NEXT_PUBLIC_GRAPHQL_TOKEN=\"&lt;YOUR_GRAPHQL_API_TOKEN&gt;\"  # authorization\u304c\u5fc5\u8981\u306a\u5834\u5408\r\n<\/code><\/pre>\n<p>\u8fd9\u6b21\u6211\u4eec\u5c06\u4f7f\u7528SpaceX API\u3002<br \/>\n\u5c06\u4ee5\u4e0b\u5185\u5bb9\u6539\u5199\u4e3a\uff1a<br \/>\n\u8fd9\u6b21\u6211\u4eec\u5c06\u4f7f\u7528SpaceX\u7684\u5e94\u7528\u7a0b\u5e8f\u63a5\u53e3\u3002<\/p>\n<pre class=\"post-pre\"><code>NEXT_PUBLIC_GRAPHQL_URL=https:\/\/api.spacex.land\/graphql\/\r\n<\/code><\/pre>\n<h3>\u4e0b\u8f7d\u67b6\u6784<\/h3>\n<p>\u4eceAPI\u4e0b\u8f7d\u6a21\u5f0f\u3002<\/p>\n<pre class=\"post-pre\"><code>yarn add <span class=\"nt\">--dev<\/span> get-graphql-schema\r\nyarn get-graphql-schema https:\/\/api.spacex.land\/graphql\/ <span class=\"o\">&gt;<\/span> schema.graphql\r\n<\/code><\/pre>\n<h2>\u4f9b\u5e94\u5546<\/h2>\n<pre class=\"post-pre\"><code><span class=\"nd\">@react.component<\/span>\r\n<span class=\"k\">let<\/span> <span class=\"n\">make<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span>~<span class=\"n\">children<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"o\">&lt;<\/span><span class=\"nn\">RescriptRelay<\/span><span class=\"p\">.<\/span><span class=\"nn\">Context<\/span><span class=\"p\">.<\/span><span class=\"nc\">Provider<\/span> <span class=\"n\">environment<\/span><span class=\"o\">=<\/span><span class=\"nn\">RelayEnv<\/span><span class=\"p\">.<\/span><span class=\"n\">environment<\/span><span class=\"o\">&gt;<\/span>\r\n    <span class=\"o\">&lt;<\/span><span class=\"n\">div<\/span><span class=\"o\">&gt;<\/span>\r\n        <span class=\"n\">children<\/span>\r\n    <span class=\"o\">&lt;\/<\/span><span class=\"n\">div<\/span><span class=\"o\">&gt;<\/span>\r\n<span class=\"o\">&lt;\/<\/span><span class=\"nn\">RescriptRelay<\/span><span class=\"p\">.<\/span><span class=\"nn\">Context<\/span><span class=\"p\">.<\/span><span class=\"nc\">Provider<\/span><span class=\"o\">&gt;<\/span>\r\n\r\n<span class=\"k\">let<\/span> <span class=\"n\">default<\/span> <span class=\"o\">=<\/span> <span class=\"n\">make<\/span>\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code><span class=\"k\">import<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">..\/..\/styles\/main.css<\/span><span class=\"dl\">'<\/span>\r\n<span class=\"k\">import<\/span> <span class=\"nx\">App<\/span> <span class=\"k\">from<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">..\/components\/App.bs<\/span><span class=\"dl\">'<\/span>\r\n\r\n<span class=\"kd\">const<\/span> <span class=\"nx\">MyApp<\/span> <span class=\"o\">=<\/span> <span class=\"p\">({<\/span> <span class=\"nx\">Component<\/span><span class=\"p\">,<\/span> <span class=\"nx\">pageProps<\/span> <span class=\"p\">})<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">(<\/span><span class=\"o\">&lt;<\/span><span class=\"nx\">App<\/span><span class=\"o\">&gt;<\/span>\r\n        <span class=\"o\">&lt;<\/span><span class=\"nx\">Component<\/span> <span class=\"p\">{...<\/span><span class=\"nx\">pageProps<\/span><span class=\"p\">}<\/span> <span class=\"sr\">\/<\/span><span class=\"err\">&gt;\r\n<\/span><span class=\"o\">&lt;<\/span><span class=\"sr\">\/App&gt;<\/span><span class=\"se\">)<\/span><span class=\"err\">;\r\n<\/span>\r\n<span class=\"k\">export<\/span> <span class=\"k\">default<\/span> <span class=\"nx\">MyApp<\/span><span class=\"p\">;<\/span>\r\n<\/code><\/pre>\n<h2>GraphQL \u6253\u51fb\u7ec4\u4ef6<\/h2>\n<pre class=\"post-pre\"><code><span class=\"k\">module<\/span> <span class=\"nc\">MyQuery<\/span> <span class=\"o\">=<\/span> <span class=\"o\">%<\/span><span class=\"n\">relay<\/span><span class=\"p\">(<\/span>\r\n    <span class=\"s2\">`query FetchMissionsQuery {\r\n        missions {\r\n             name\r\n             id\r\n             description\r\n        }\r\n    }`<\/span>\r\n<span class=\"p\">)<\/span>\r\n\r\n<span class=\"nd\">@react.component<\/span>\r\n<span class=\"k\">let<\/span> <span class=\"n\">make<\/span> <span class=\"o\">=<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"k\">let<\/span> <span class=\"n\">response<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">MyQuery<\/span><span class=\"p\">.<\/span><span class=\"n\">use<\/span><span class=\"p\">(<\/span>~<span class=\"n\">variables<\/span><span class=\"o\">=<\/span><span class=\"p\">()<\/span>, <span class=\"p\">())<\/span>\r\n\r\n    <span class=\"k\">let<\/span> <span class=\"n\">missions<\/span> <span class=\"o\">=<\/span> <span class=\"k\">switch<\/span> <span class=\"p\">(<\/span><span class=\"n\">response<\/span>.<span class=\"n\">missions<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n       <span class=\"o\">|<\/span> <span class=\"nc\">Some<\/span><span class=\"p\">(<\/span><span class=\"n\">data<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"n\">data<\/span>\r\n       <span class=\"o\">|<\/span> <span class=\"n\">_<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">[]<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n    <span class=\"o\">&lt;<\/span><span class=\"n\">div<\/span><span class=\"o\">&gt;<\/span>\r\n        <span class=\"o\">&lt;<\/span><span class=\"n\">div<\/span><span class=\"o\">&gt;&lt;<\/span><span class=\"n\">p<\/span> <span class=\"n\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"font-black\"<\/span><span class=\"o\">&gt;<\/span><span class=\"p\">{<\/span><span class=\"nn\">React<\/span><span class=\"p\">.<\/span><span class=\"n\">string<\/span><span class=\"p\">(<\/span><span class=\"s2\">\"missions\"<\/span><span class=\"p\">)}<\/span><span class=\"o\">&lt;\/<\/span><span class=\"n\">p<\/span><span class=\"o\">&gt;&lt;\/<\/span><span class=\"n\">div<\/span><span class=\"o\">&gt;<\/span>\r\n        <span class=\"p\">{<\/span>\r\n            <span class=\"n\">missions<\/span>\r\n            <span class=\"o\">-&gt;<\/span><span class=\"nn\">Belt<\/span><span class=\"p\">.<\/span><span class=\"nn\">Array<\/span><span class=\"p\">.<\/span><span class=\"n\">map<\/span><span class=\"p\">(<\/span>\r\n                <span class=\"n\">mission<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"k\">switch<\/span><span class=\"p\">(<\/span><span class=\"n\">mission<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n                    <span class=\"o\">|<\/span> <span class=\"nc\">Some<\/span><span class=\"p\">(<\/span><span class=\"n\">data<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span>  <span class=\"o\">&lt;<\/span><span class=\"n\">div<\/span> <span class=\"n\">key<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"nn\">Belt<\/span><span class=\"p\">.<\/span><span class=\"nn\">Option<\/span><span class=\"p\">.<\/span><span class=\"n\">getWithDefault<\/span><span class=\"p\">(<\/span><span class=\"n\">data<\/span>.<span class=\"n\">id<\/span>, <span class=\"s2\">\"XXXXX\"<\/span><span class=\"p\">)}<\/span><span class=\"o\">&gt;<\/span>\r\n                            <span class=\"o\">&lt;<\/span><span class=\"n\">div<\/span><span class=\"o\">&gt;&lt;<\/span><span class=\"n\">p<\/span> <span class=\"n\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"font-medium\"<\/span><span class=\"o\">&gt;<\/span><span class=\"p\">{<\/span><span class=\"nn\">React<\/span><span class=\"p\">.<\/span><span class=\"n\">string<\/span><span class=\"p\">(<\/span><span class=\"nn\">Belt<\/span><span class=\"p\">.<\/span><span class=\"nn\">Option<\/span><span class=\"p\">.<\/span><span class=\"n\">getWithDefault<\/span><span class=\"p\">(<\/span><span class=\"n\">data<\/span>.<span class=\"n\">name<\/span>, <span class=\"s2\">\"\"<\/span><span class=\"p\">))}<\/span><span class=\"o\">&lt;\/<\/span><span class=\"n\">p<\/span><span class=\"o\">&gt;&lt;\/<\/span><span class=\"n\">div<\/span><span class=\"o\">&gt;<\/span>\r\n                            <span class=\"o\">&lt;<\/span><span class=\"n\">div<\/span><span class=\"o\">&gt;<\/span><span class=\"p\">{<\/span><span class=\"nn\">React<\/span><span class=\"p\">.<\/span><span class=\"n\">string<\/span><span class=\"p\">(<\/span><span class=\"nn\">Belt<\/span><span class=\"p\">.<\/span><span class=\"nn\">Option<\/span><span class=\"p\">.<\/span><span class=\"n\">getWithDefault<\/span><span class=\"p\">(<\/span><span class=\"n\">data<\/span>.<span class=\"n\">description<\/span>, <span class=\"s2\">\"\"<\/span><span class=\"p\">))}<\/span><span class=\"o\">&lt;\/<\/span><span class=\"n\">div<\/span><span class=\"o\">&gt;<\/span>\r\n                            <span class=\"o\">&lt;<\/span><span class=\"n\">hr<\/span><span class=\"o\">\/&gt;<\/span>\r\n                        <span class=\"o\">&lt;\/<\/span><span class=\"n\">div<\/span><span class=\"o\">&gt;<\/span>\r\n                    <span class=\"o\">|<\/span> <span class=\"n\">_<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"o\">&lt;&gt;&lt;\/&gt;<\/span>\r\n                <span class=\"p\">}<\/span>\r\n            <span class=\"p\">)<\/span><span class=\"o\">-&gt;<\/span><span class=\"nn\">React<\/span><span class=\"p\">.<\/span><span class=\"n\">array<\/span>\r\n        <span class=\"p\">}<\/span>\r\n    <span class=\"o\">&lt;\/<\/span><span class=\"n\">div<\/span><span class=\"o\">&gt;<\/span>\r\n<span class=\"p\">}<\/span>\r\n\r\n<span class=\"k\">let<\/span> <span class=\"n\">default<\/span> <span class=\"o\">=<\/span> <span class=\"n\">make<\/span>\r\n<\/code><\/pre>\n<div><img decoding=\"async\" class=\"post-images\" title=\"\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d8105913a08637a6ac0b4\/43-0.png\" alt=\"\uff27\uff52\uff41\uff50\uff48\uff31\uff2c Page\" \/><\/div>\n<p>\u5173\u4e8e\u54cd\u5e94\u7c7b\u578b\uff0c\u4f1a\u5728\u901a\u8fc7\u4e0b\u8f7d\u7684schema.graphql\u521b\u5efa\u7684.res\u6587\u4ef6\u4e2d\uff0c\u4f7f\u7528realy:watch\u547d\u4ee4\u8fdb\u884c\u8bb0\u5f55\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"cm\">\/* @generated *\/<\/span>\r\n<span class=\"o\">%%<\/span><span class=\"n\">raw<\/span><span class=\"p\">(<\/span><span class=\"s2\">\"\/* @generated *\/\"<\/span><span class=\"p\">)<\/span>\r\n<span class=\"k\">module<\/span> <span class=\"nc\">Types<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"o\">@@<\/span><span class=\"n\">ocaml<\/span>.<span class=\"n\">warning<\/span><span class=\"p\">(<\/span><span class=\"s2\">\"-30\"<\/span><span class=\"p\">)<\/span>\r\n\r\n  <span class=\"k\">type<\/span> <span class=\"k\">rec<\/span> <span class=\"n\">response_missions<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"n\">name<\/span>: <span class=\"kt\">option<\/span><span class=\"o\">&lt;<\/span><span class=\"kt\">string<\/span><span class=\"o\">&gt;<\/span>,\r\n    <span class=\"n\">id<\/span>: <span class=\"kt\">option<\/span><span class=\"o\">&lt;<\/span><span class=\"kt\">string<\/span><span class=\"o\">&gt;<\/span>,\r\n    <span class=\"n\">description<\/span>: <span class=\"kt\">option<\/span><span class=\"o\">&lt;<\/span><span class=\"kt\">string<\/span><span class=\"o\">&gt;<\/span>,\r\n  <span class=\"p\">}<\/span>\r\n  <span class=\"k\">type<\/span> <span class=\"n\">response<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"n\">missions<\/span>: <span class=\"kt\">option<\/span><span class=\"o\">&lt;<\/span><span class=\"kt\">array<\/span><span class=\"o\">&lt;<\/span><span class=\"kt\">option<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">response_missions<\/span><span class=\"o\">&gt;&gt;&gt;<\/span>,\r\n  <span class=\"p\">}<\/span>\r\n  <span class=\"k\">type<\/span> <span class=\"n\">rawResponse<\/span> <span class=\"o\">=<\/span> <span class=\"n\">response<\/span>\r\n  <span class=\"k\">type<\/span> <span class=\"n\">variables<\/span> <span class=\"o\">=<\/span> <span class=\"kt\">unit<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>\u4e3a\u4ec0\u4e48option\u662fid\u5462\uff1f\u5982\u679c\u4f7f\u7528iteration\uff0c\u6bcf\u4e2a\u7ec4\u4ef6\u90fd\u9700\u8981\u6709\u4e00\u4e2a\u72ec\u7279\u7684key\uff0c\u4f46\u662f\u5982\u679c\u6ca1\u6709id\u7684\u8bdd\u5e94\u8be5\u4f1a\u88ab\u62a5\u9519\u2026<br \/>\n\u56e0\u4e3a\u6709option\u5b58\u5728\uff0c\u53bb\u9664\u5b83\u4f1a\u5f88\u9ebb\u70e6\uff0c\u6240\u4ee5\u5e0c\u671b\u80fd\u6709\u5176\u4ed6\u7684\u89e3\u51b3\u529e\u6cd5\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nd\">@react.component<\/span>\r\n<span class=\"k\">let<\/span> <span class=\"n\">make<\/span> <span class=\"o\">=<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"o\">&lt;<\/span><span class=\"n\">div<\/span><span class=\"o\">&gt;<\/span>\r\n        <span class=\"o\">&lt;<\/span><span class=\"nc\">Header<\/span> <span class=\"o\">\/&gt;<\/span>\r\n        <span class=\"o\">&lt;<\/span><span class=\"n\">div<\/span> <span class=\"n\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"py-6 md:py-12\"<\/span><span class=\"o\">&gt;<\/span>\r\n            <span class=\"o\">&lt;<\/span><span class=\"n\">div<\/span> <span class=\"n\">className<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"container px-4 mx-auto\"<\/span><span class=\"o\">&gt;<\/span>\r\n                <span class=\"o\">&lt;<\/span><span class=\"nn\">React<\/span><span class=\"p\">.<\/span><span class=\"nc\">Suspense<\/span> <span class=\"n\">fallback<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">div<\/span><span class=\"o\">&gt;<\/span><span class=\"p\">{<\/span><span class=\"nn\">React<\/span><span class=\"p\">.<\/span><span class=\"n\">string<\/span><span class=\"p\">(<\/span><span class=\"s2\">`Loading...`<\/span><span class=\"p\">)}<\/span><span class=\"o\">&lt;\/<\/span><span class=\"n\">div<\/span><span class=\"o\">&gt;<\/span><span class=\"p\">}<\/span><span class=\"o\">&gt;<\/span>\r\n                    <span class=\"o\">&lt;<\/span><span class=\"nc\">FetchMissions<\/span> <span class=\"o\">\/&gt;<\/span>\r\n                <span class=\"o\">&lt;\/<\/span><span class=\"nn\">React<\/span><span class=\"p\">.<\/span><span class=\"nc\">Suspense<\/span><span class=\"o\">&gt;<\/span>\r\n            <span class=\"o\">&lt;\/<\/span><span class=\"n\">div<\/span><span class=\"o\">&gt;<\/span>\r\n        <span class=\"o\">&lt;\/<\/span><span class=\"n\">div<\/span><span class=\"o\">&gt;<\/span>\r\n    <span class=\"o\">&lt;\/<\/span><span class=\"n\">div<\/span><span class=\"o\">&gt;<\/span>\r\n<span class=\"p\">}<\/span>\r\n\r\n<span class=\"k\">let<\/span> <span class=\"n\">default<\/span> <span class=\"o\">=<\/span> <span class=\"n\">make<\/span>\r\n<\/code><\/pre>\n<p>\u4f7f\u7528Relay\u7684\u7ec4\u4ef6\u5916\u90e8\u4f7f\u7528React.Suspense\u5305\u88f9\uff0c\u5e76\u5728Suspense\u6807\u7b7e\u5185\u6307\u5b9a\u5728\u51fa\u73b0fallback\u7684\u60c5\u51b5\u4e0b\uff08\u5373\u5c1a\u672a\u52a0\u8f7d\u6216\u52a0\u8f7d\u5931\u8d25\u65f6\uff09\u8981\u663e\u793a\u7684\u7ec4\u4ef6\u3002<br \/>\n\u53ea\u5728\u5916\u90e8\u8fdb\u884c\u5305\u88f9\u5373\u53ef\uff0c\u4f8b\u5982\u5728src\/components\/App.res\u7684<\/p>\n<div><\/div>\n<p>\u7684\u5916\u90e8\u4f7f\u7528Suspense\u5305\u88f9\u4e5f\u53ef\u4ee5\u3002\u4f46\u662f\u6574\u4f53\u4f1a\u88ab\u89c6\u4e3a\u6b63\u5728\u52a0\u8f7d\u4e2d\u7684\u72b6\u6001\uff0c\u6240\u4ee5\u57fa\u672c\u4e0a\u4e0d\u4f1a\u8fd9\u6837\u505a\u3002<\/p>\n<h1>\u6267\u884cdev<\/h1>\n<pre class=\"post-pre\"><code>yarn relay:watch\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code>yarn dev:rescript\r\n<\/code><\/pre>\n<p>\u5c06`yarn dev:reason`\u547d\u540d\u4e3a\u5176\u4ed6\u540d\u79f0\u3002<\/p>\n<pre class=\"post-pre\"><code>yarn dev:next\r\n<\/code><\/pre>\n<p>\u8bbf\u95eehttp:\/\/localhost:3000\/missions\u3002<\/p>\n<div><img decoding=\"async\" class=\"post-images\" title=\"\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d8105913a08637a6ac0b4\/55-0.png\" alt=\"\u30a2\u30af\u30bb\u30b9\u7d50\u679c\" \/><\/div>\n<h1>\u5370\u8c61<\/h1>\n<p>\u5bf9\u4e8e\u67e5\u8be2\u540d\u79f0\u7684\u6307\u5b9a\u6709\u4e00\u4e9b\u7279\u6b8a\u8981\u6c42\u3002<br \/>\n\u6e90\u76ee\u5f55\u4f1a\u53d7\u9650\u5236\u3002<br \/>\n\u53ef\u4ee5\u4f7f\u7528GraphQL\u548cfetch\u8fdb\u884c\u8c03\u7528\u3002<br \/>\n\u5f53\u5b58\u5728\u591a\u4e2a\u7ec8\u70b9\u65f6\u8be5\u600e\u4e48\u529e\uff1f\uff08\u53ef\u80fd\u4e0d\u592a\u5e38\u89c1\u7684\u60c5\u51b5\uff1f\uff09<\/p>\n<h1>\u505a\u4e86\u4f46\u4e0d\u6210\u529f\u7684\u4e8b\u60c5<\/h1>\n<h2>\u91cd\u5199-\u963f\u6ce2\u7f57\u5ba2\u6237\u7aef<\/h2>\n<h3>\u4e00) \u80cc\u666f<\/h3>\n<p>\u4e8c)\u6839\u636e<\/p>\n<p>\u4e09) \u7531\u4e8e<\/p>\n<p>\u4f9d\u8d56\u9879\u662f reason-react\u3002\u5c3d\u7ba1\u5c1d\u8bd5\u4e86\u5f3a\u5236\u4fee\u6539\u5e76\u91cd\u65b0\u6784\u5efa\uff0c\u4f46\u5e76\u672a\u6210\u529f\u3002<\/p>\n<p>\u53d1\u751f\u4e86\u65e0\u6548\u7684hook\u9519\u8bef\uff0c\u65e0\u6cd5\u4fee\u590d\u3002<\/p>\n<h2>\u4ea4\u6362<\/h2>\n<p>\u63d0\u4f9b\u8fd4\u56de\u300a\u661f\u7403\u5927\u6218\u300b\u89d2\u8272\u540d\u79f0\u7b49\u76f8\u5173API\u96c6\u5408\u3002\u6700\u521d\u6211\u6253\u7b97\u4f7f\u7528\u8fd9\u4e2a\u3002<\/p>\n<p>swapi-qlaphql\uff08GitHub\uff09<br \/>\nswapi-graphql \u6d4b\u8bd5\u9875\u9762<\/p>\n<p>\u6211\u5728\u4f7f\u7528get-graphql-schema\u65f6\u6536\u5230\u4e86\u65e0\u6548\u7684JSON\u3002\u4e3a\u4ec0\u4e48\u4f1a\u8fd9\u6837\uff1f<\/p>\n<h1>\u5b9e\u9645\u5e94\u7528<\/h1>\n<p>\u6211\u4eec\u6b63\u5728\u4f7f\u7528graphCMS\u4ee5\u76f8\u540c\u7684\u7ed3\u6784\u3002<\/p>\n<h1>\u8bf7\u67e5\u9605\u53c2\u8003\u6587\u732e\u3002<br \/>\n\u6216\u8005<br \/>\n\u8bf7\u8e0f\u5165\u53c2\u8003\u6587\u732e\u3002<\/h1>\n<p>GraphQL<br \/>\nGraphQL\u4ee3\u7801\u5e93\u3001\u5de5\u5177\u548c\u670d\u52a1<br \/>\nApollo<br \/>\nApollo\u5ba2\u6237\u7aef<br \/>\nRescript Apollo\u5ba2\u6237\u7aef<br \/>\nRelay<br \/>\nRescriptRelay<br \/>\n\u5f00\u59cb\u4f7f\u7528RescriptRelay | RescriptRelay<br \/>\n\u4f7f\u7528\u60ac\u6302\u529f\u80fd\u83b7\u53d6\u6570\u636e\uff08\u5b9e\u9a8c\u6027\u529f\u80fd\uff09<br \/>\n\u4f7f\u7528ReasonML\u5728Next.js\u4e2d\u8fdb\u884c\u9875\u9762\u8f6c\u6362\u5e76\u663e\u793aWeb API\u7684\u54cd\u5e94 &#8211; \u6dfb\u52a0bs-fetch\u3001bs-json<br \/>\nswapi-qlaphql\uff08GitHub\uff09<br \/>\nswapi-graphql\u6d4b\u8bd5\u9875\u9762<br \/>\nSpaceX API<br \/>\nNext.js &#8211; \u57fa\u672c\u529f\u80fd\uff1a\u73af\u5883\u53d8\u91cf &#8211; \u5c06\u73af\u5883\u53d8\u91cf\u66b4\u9732\u7ed9\u6d4f\u89c8\u5668<br \/>\ngraphCMS<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u5728\u57fa\u4e8eNext.js\uff0cReScript\u548ctailwind\u7684\u73af\u5883\u4e2d\uff0c\u5c1d\u8bd5\u4f7f\u7528GraphQL\u8fdb\u884c\u5f00\u53d1\u3002 \u56fe\u7075\u5b8c\u5907\u67e5 [&hellip;]<\/p>\n","protected":false},"author":11,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-47830","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v21.5 (Yoast SEO v21.5) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>\u5728ReScript x Next.js\u73af\u5883\u4e2d\u5f15\u5165GraphQL\u5e93&quot;Relay&quot; - Blog - Silicon Cloud<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.silicloud.com\/zh\/blog\/\u5728rescript-x-next-js\u73af\u5883\u4e2d\u5f15\u5165graphql\u5e93relay\u3002\/\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\u5728ReScript x Next.js\u73af\u5883\u4e2d\u5f15\u5165GraphQL\u5e93&quot;Relay&quot;\" \/>\n<meta property=\"og:description\" content=\"\u5728\u57fa\u4e8eNext.js\uff0cReScript\u548ctailwind\u7684\u73af\u5883\u4e2d\uff0c\u5c1d\u8bd5\u4f7f\u7528GraphQL\u8fdb\u884c\u5f00\u53d1\u3002 \u56fe\u7075\u5b8c\u5907\u67e5 [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.silicloud.com\/zh\/blog\/\u5728rescript-x-next-js\u73af\u5883\u4e2d\u5f15\u5165graphql\u5e93relay\u3002\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog - Silicon Cloud\" \/>\n<meta property=\"article:published_time\" content=\"2023-01-22T13:02:02+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-04-30T03:35:03+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d8105913a08637a6ac0b4\/43-0.png\" \/>\n<meta name=\"author\" content=\"\u65b0, \u97f5\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"\u65b0, \u97f5\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8rescript-x-next-js%e7%8e%af%e5%a2%83%e4%b8%ad%e5%bc%95%e5%85%a5graphql%e5%ba%93relay%e3%80%82\/\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8rescript-x-next-js%e7%8e%af%e5%a2%83%e4%b8%ad%e5%bc%95%e5%85%a5graphql%e5%ba%93relay%e3%80%82\/\",\"name\":\"\u5728ReScript x Next.js\u73af\u5883\u4e2d\u5f15\u5165GraphQL\u5e93\\\"Relay\\\" - Blog - Silicon Cloud\",\"isPartOf\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\"},\"datePublished\":\"2023-01-22T13:02:02+00:00\",\"dateModified\":\"2024-04-30T03:35:03+00:00\",\"author\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/4ba4019495123db3038fd0809e6959c9\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8rescript-x-next-js%e7%8e%af%e5%a2%83%e4%b8%ad%e5%bc%95%e5%85%a5graphql%e5%ba%93relay%e3%80%82\/#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8rescript-x-next-js%e7%8e%af%e5%a2%83%e4%b8%ad%e5%bc%95%e5%85%a5graphql%e5%ba%93relay%e3%80%82\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8rescript-x-next-js%e7%8e%af%e5%a2%83%e4%b8%ad%e5%bc%95%e5%85%a5graphql%e5%ba%93relay%e3%80%82\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.silicloud.com\/zh\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u5728ReScript x Next.js\u73af\u5883\u4e2d\u5f15\u5165GraphQL\u5e93&#8221;Relay&#8221;\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/\",\"name\":\"Blog - Silicon Cloud\",\"description\":\"\",\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/4ba4019495123db3038fd0809e6959c9\",\"name\":\"\u65b0, \u97f5\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/d484b6c6e4ae82e8a9efea989e1d2af46d9b6ef128101e63b18f559fca0ae627?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/d484b6c6e4ae82e8a9efea989e1d2af46d9b6ef128101e63b18f559fca0ae627?s=96&d=mm&r=g\",\"caption\":\"\u65b0, \u97f5\"},\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/author\/yunxin\/\"},{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8rescript-x-next-js%e7%8e%af%e5%a2%83%e4%b8%ad%e5%bc%95%e5%85%a5graphql%e5%ba%93relay%e3%80%82\/#local-main-organization-logo\",\"url\":\"\",\"contentUrl\":\"\",\"caption\":\"Blog - Silicon Cloud\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"\u5728ReScript x Next.js\u73af\u5883\u4e2d\u5f15\u5165GraphQL\u5e93\"Relay\" - Blog - Silicon Cloud","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.silicloud.com\/zh\/blog\/\u5728rescript-x-next-js\u73af\u5883\u4e2d\u5f15\u5165graphql\u5e93relay\u3002\/","og_locale":"zh_CN","og_type":"article","og_title":"\u5728ReScript x Next.js\u73af\u5883\u4e2d\u5f15\u5165GraphQL\u5e93\"Relay\"","og_description":"\u5728\u57fa\u4e8eNext.js\uff0cReScript\u548ctailwind\u7684\u73af\u5883\u4e2d\uff0c\u5c1d\u8bd5\u4f7f\u7528GraphQL\u8fdb\u884c\u5f00\u53d1\u3002 \u56fe\u7075\u5b8c\u5907\u67e5 [&hellip;]","og_url":"https:\/\/www.silicloud.com\/zh\/blog\/\u5728rescript-x-next-js\u73af\u5883\u4e2d\u5f15\u5165graphql\u5e93relay\u3002\/","og_site_name":"Blog - Silicon Cloud","article_published_time":"2023-01-22T13:02:02+00:00","article_modified_time":"2024-04-30T03:35:03+00:00","og_image":[{"url":"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/657d8105913a08637a6ac0b4\/43-0.png"}],"author":"\u65b0, \u97f5","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"\u65b0, \u97f5","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"4 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8rescript-x-next-js%e7%8e%af%e5%a2%83%e4%b8%ad%e5%bc%95%e5%85%a5graphql%e5%ba%93relay%e3%80%82\/","url":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8rescript-x-next-js%e7%8e%af%e5%a2%83%e4%b8%ad%e5%bc%95%e5%85%a5graphql%e5%ba%93relay%e3%80%82\/","name":"\u5728ReScript x Next.js\u73af\u5883\u4e2d\u5f15\u5165GraphQL\u5e93\"Relay\" - Blog - Silicon Cloud","isPartOf":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website"},"datePublished":"2023-01-22T13:02:02+00:00","dateModified":"2024-04-30T03:35:03+00:00","author":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/4ba4019495123db3038fd0809e6959c9"},"breadcrumb":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8rescript-x-next-js%e7%8e%af%e5%a2%83%e4%b8%ad%e5%bc%95%e5%85%a5graphql%e5%ba%93relay%e3%80%82\/#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8rescript-x-next-js%e7%8e%af%e5%a2%83%e4%b8%ad%e5%bc%95%e5%85%a5graphql%e5%ba%93relay%e3%80%82\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8rescript-x-next-js%e7%8e%af%e5%a2%83%e4%b8%ad%e5%bc%95%e5%85%a5graphql%e5%ba%93relay%e3%80%82\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.silicloud.com\/zh\/blog\/"},{"@type":"ListItem","position":2,"name":"\u5728ReScript x Next.js\u73af\u5883\u4e2d\u5f15\u5165GraphQL\u5e93&#8221;Relay&#8221;"}]},{"@type":"WebSite","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website","url":"https:\/\/www.silicloud.com\/zh\/blog\/","name":"Blog - Silicon Cloud","description":"","inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/4ba4019495123db3038fd0809e6959c9","name":"\u65b0, \u97f5","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/d484b6c6e4ae82e8a9efea989e1d2af46d9b6ef128101e63b18f559fca0ae627?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d484b6c6e4ae82e8a9efea989e1d2af46d9b6ef128101e63b18f559fca0ae627?s=96&d=mm&r=g","caption":"\u65b0, \u97f5"},"url":"https:\/\/www.silicloud.com\/zh\/blog\/author\/yunxin\/"},{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8rescript-x-next-js%e7%8e%af%e5%a2%83%e4%b8%ad%e5%bc%95%e5%85%a5graphql%e5%ba%93relay%e3%80%82\/#local-main-organization-logo","url":"","contentUrl":"","caption":"Blog - Silicon Cloud"}]}},"_links":{"self":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/47830","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/users\/11"}],"replies":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/comments?post=47830"}],"version-history":[{"count":2,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/47830\/revisions"}],"predecessor-version":[{"id":91667,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/47830\/revisions\/91667"}],"wp:attachment":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/media?parent=47830"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/categories?post=47830"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/tags?post=47830"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}