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;
■ 参考のコード