見出し画像

Rust Webassembly , React + IndexedDB で CRUD作成 #Rust #Webassembly #javascript #React

■ 概要:

Rust Webassembly (下記 wasm) 関係になり。
IndexedDB + React + webpack で、CRUD作成する内容となります。

・React CRUDに、表示系をwasm で、実装する形です。
・webpack + React 準備は、前の記事を参考にしています。

■ 前の関連ページ,webpack + React

https://note.com/knaka0209/n/nc7f663d5d6f6

■ 環境

Rust
rustc 1.46.0
cargo 1.46.0
wasm-pack
React 16
react-router 5.0
node 12.18.3
webpack
IndexedDB
dexie

■ デモのページ

https://kuc-arc-f.github.io/wasm-idx-sample/#/task

■ プロジェクト作成、ビルド

cargo generate --git https://github.com/rustwasm/wasm-pack-template

wasm-pack build

npm init wasm-app www

npm install

■ 実装など

・Rust, lib.rs : DOM操作
リスト、詳細

#[wasm_bindgen]
pub fn wasm_task_row(id_name: &str, json: &str) -> Result<(), JsValue>{
   let v: Value = serde_json::from_str( json ).unwrap();
   let tmp_title = v["title"].to_string();
   let title = tmp_title.replace('"', "");
   let id_val = v["id"].to_string();
   let tmp_date = v["created_at"].to_string();
   let date_val = tmp_date.replace('"', "");

   let document = web_sys::window().unwrap().document().unwrap();
   let entry_point = document.get_element_by_id(id_name).unwrap();
   let val = document.create_element("div")?;
   let s_elm = format!("
       <a href='#/task_show/{}'>
           <h3 class='h3_title'>{}</h3>
       </a>        
       <div class='div_post_date_wrap'>
           <p class='mb-0'>
               <span class='mr-2 time_icon_wrap'><i class='far fa-calendar'></i></span>
               {} ,
               <span>ID :{}</span>
               <a href='#/task_edit/{}' class='btn btn-sm btn-outline-primary ml-2'>
               Edit</a>
           </p>
       </div>
       <hr class='hr_ex1'>", id_val ,title, date_val, id_val, id_val );
   val.set_inner_html(&s_elm );
   entry_point.append_child(&val)?;

   Ok(())
}

#[wasm_bindgen]
pub fn wasm_show_disp(id_name: &str, json: &str) -> Result<(), JsValue>{
   let v: Value = serde_json::from_str( json ).unwrap();
   let tmp_title = v["title"].to_string();
   let title = tmp_title.replace('"', "");
   let tmp_date = v["created_at"].to_string();
   let date_val = tmp_date.replace('"', "");
   let tmp_content = v["content"].to_string();
   let content_val = tmp_content.replace('"', "");
//console::log_1(&JsValue::from_str( &id_name ));

   let document = web_sys::window().unwrap().document().unwrap();
   let entry_point = document.get_element_by_id(id_name).unwrap();
   let val = document.create_element("div")?;
   let s_elm = format!("
       <h1>{}</h1>
       Date : {}<hr>
       {} <br />
       <br />", title, date_val, content_val);
   val.set_inner_html(&s_elm );
   entry_point.append_child(&val)?;

   Ok(())
}

・ js, wasm 呼出し

www/src/component/Task/Index.js

    tabRow(){
       if(this.state.data instanceof Array){
           return this.state.data.map(function(object, i){
//console.log( object )
               var json = JSON.stringify( object );
               wasm.wasm_task_row("div_post_wrap", String(json) );
           })
       }
   }

・ App.js
www/src/App.js

class App extends Component {
 render() {
   return (
     <div className="App">
       <Router>
       <Navbar />
         <div>
           <Route exact path='/' component={Home}/>
           <Route path='/about' component={About}/>

           <Route path='/task' component={TaskIndex}/>
           <Route path='/task_create' component={TaskCreate}/>
           <Route path='/task_edit/:id' component={TaskEdit}/> 
           <Route path='/task_show/:id' component={TaskShow}/>
           <Route path='/task_import' component={TaskImportTask}/>
           <Route path='/task_test' component={TaskTest}/>
         </div>
       </Router>
       <Footer />
     </div>
   );
 }
}
export default App;


■ 参考のコード





いいなと思ったら応援しよう!