## 步驟
### 創(chuàng)建工程
1. 準備工作(搭建react-native開發(fā)環(huán)境[搭建開發(fā)環(huán)境](https://reactnative.cn/docs/getting-started))
2. 創(chuàng)建一個rn工程 `react-native init trainplatform`
3. 添加`shadow-cljs`依賴`yarn add shadow-cljs`
4. 手動添加shadow-cljs.end文件 `touch shadow-cljs.edn`
### 初始化rn項目
在所建文件夾根目錄下執(zhí)行(默認你已經有一定rn基礎堂竟,至于rn環(huán)境的搭建[請閱讀此教程](https://reactnative.cn/docs/getting-started))
`react-native init trainplatform`
進入reactnative工程下面澄峰,運行rn項目
```
cd reactnative
react-native run-ios
```
稍等片刻,不出所料,rn工程已經運行起來了
![效果圖](https://measure.3vyd.com/Simulator%20Screen%20Shot%20-%20iPhone%2011%20-%202020-05-28%20at%2006.00.09.png)
### 添加必要的依賴庫
還是在reactnative工程目錄下面為rn項目添加`react-dom`庫。
`yarn add react-dom`
添加`shadow-cljs`開發(fā)環(huán)境依賴
`yarn add shadow-cljs --dev`
目前`reactnative`下面的`package.json`文件開起來應該是這樣的
```
{
? "name": "reactnative",
? "version": "0.0.1",
? "private": true,
? "scripts": {
? ? "android": "react-native run-android",
? ? "ios": "react-native run-ios",
? ? "start": "react-native start",
? ? "test": "jest",
? ? "lint": "eslint ."
? },
? "dependencies": {
? ? "react": "16.11.0",
? ? "react-dom": "^16.13.1",
? ? "react-native": "0.62.2"
? },
? "devDependencies": {
? ? "@babel/core": "^7.10.0",
? ? "@babel/runtime": "^7.10.0",
? ? "@react-native-community/eslint-config": "^1.1.0",
? ? "babel-jest": "^26.0.1",
? ? "eslint": "^7.1.0",
? ? "jest": "^26.0.1",
? ? "metro-react-native-babel-preset": "^0.59.0",
? ? "react-test-renderer": "16.11.0",
? ? "shadow-cljs": "^2.9.10"
? },
? "jest": {
? ? "preset": "react-native"
? }
}
```
### 修改shadow-cljs.edn 文件
回到工程root目錄,即`rn-demo`下面,編輯`shadow-cljs.edn`文件。
`vim shadow-cljs.edn`
復制以下內容:
```
;; shadow-cljs configuration
{:source-paths
["src/dev"
? "src/main"
? "src/test"]
:dependencies
[[Reagent "0.9.1"]]
:builds
{:app
? {:target :react-native
? :init-fn rc.app/init
? :output-dir "build"
? :js-options {:js-package-dirs ["reactnative/node_modules"]}}}}
```
注意:依賴一定要添加`Reagent`椎扬。`target`就是rn項目創(chuàng)建的項目名字,咱們起的名字就叫`reactnative`,當然你也可以起別的喜歡的名字具温,`output-dir`就是指定cljs編譯成js之后存放的目錄蚕涤,`js-options`指定`cljs`引用`js`時候的目錄。
保存文件铣猩,我們進入下一步钻趋。
### clojurescript編碼
創(chuàng)建目錄`src/main/rc`,并在此目錄下新建文件`app.cljs`.編輯文件如下:
```
(ns rc.app
? (:require
? ["create-react-class" :as crc]
? ["react-native" :as rn]
? [reagent.core :as r]))
;; must use defonce and must refresh full app so metro can fill these in
;; at live-reload time `require` does not exist and will cause errors
;; must use path relative to :output-dir
(defn root []
[:> rn/Text {:style {:fontSize 90 :marginTop 100}} "hello world" ])
(defonce root-ref (atom nil))
(defonce root-component-ref (atom nil))
(defn render-root [root]
? (let [first-call? (nil? @root-ref)]
? ? (reset! root-ref root)
? ? (if-not first-call?
? ? ? (when-let [root @root-component-ref]
? ? ? ? (.forceUpdate root))
? ? ? (let [Root
? ? ? ? ? ? (crc
? ? ? ? ? ? #js {:componentDidMount
? ? ? ? ? ? ? ? ? (fn []
? ? ? ? ? ? ? ? ? ? (this-as this
? ? ? ? ? ? ? ? ? ? ? (reset! root-component-ref this)))
? ? ? ? ? ? ? ? ? :componentWillUnmount
? ? ? ? ? ? ? ? ? (fn []
? ? ? ? ? ? ? ? ? ? (reset! root-component-ref nil))
? ? ? ? ? ? ? ? ? :render
? ? ? ? ? ? ? ? ? (fn []
? ? ? ? ? ? ? ? ? ? (let [body @root-ref]
? ? ? ? ? ? ? ? ? ? ? (if (fn? body)
? ? ? ? ? ? ? ? ? ? ? ? (body)
? ? ? ? ? ? ? ? ? ? ? ? body)))})]
? ? ? ? (rn/AppRegistry.registerComponent "trainplatform" (fn [] Root))))))
(defn start
? {:dev/after-load true}
? []
? (render-root (r/as-element [root])))
(defn init []
? (start))
```
### 讓react-native加載cljs編譯生成的js代碼
至此,我們就差讓rn項目加載cljs編譯生成的js代碼了剂习,回到reactnative目錄蛮位,打開`index.js`,修改為:
```
///////////////////////////////////////////////////////
// import {AppRegistry} from 'react-native';? ? ? ? //
// import App from './App';? ? ? ? ? ? ? ? ? ? ? ? ? //
// import {name as appName} from './app.json';? ? ? //
//? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //
// AppRegistry.registerComponent(appName, () => App); //
///////////////////////////////////////////////////////
import "./app/index.js";
```
這樣當我們編輯clojurescript代碼的時候,rn就會實時reload鳞绕。最終效果:
![最終效果](https://measure.3vyd.com/%E6%95%88%E6%9E%9C19989.png)