2020年1月20日月曜日

ReactをJavaScriptのみで使う

おじさん、最近のフロントエンドには全くついていけません。
そのなかでも特にわからいのがReact。

Reactって開発者向けのライブラリで学習に時間がかかるらしい。
おじさん、開発者だけどわからないぞ。
JSXとかBabel.jsってなんなんだよ!

しかもReactはJSXを使わないでJavaScriptのみで書くととってもめんどくさい。
Vue.jsやAnglarjsみたいにJSファイルだけで使えるとよいんだけどなあ。
どうもおじさんとReactは相性が悪いらしい。

どうにかJavaScriptのみでReact使えないかなぁ。
三日間悩み続けたら、関数一つ追加すればJavaScriptのみでReactが使えるんじゃね?ということに気づきました。

というわけで、ReactをJSXを使わないでJavaScriptのみで簡単に動作するように、関数を一つ追加してみました。

ReactYo.render('#root2',data);

配列にいろいろ情報セットして、ReactYo.renderを呼ぶだけ。
これでReactをVue.jsやAngularjs風に使える!
{{}}も動作するようにしてみました。
あとforとかも実装すれば、タグの複製とかもできそう。



------------------------------
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Reactサンプル</title>
</head>
<body>
  <h1>Reactサンプル</h1>

  <div id="root"><div id="child1">hoge</div><div id="child2">hoge</div><div>{{getMsg()}}</div></div>
  <div id="root2">{{getMsg()}}</div>
  <div id="root3"><input id="input1" /></div>

  <script src="react.development.js"></script>
  <script src="react-dom.development.js"></script>
  <script src="babel.js"></script>
  <script language="Javascript">


//
// ReactYo
//

ReactYo={};
ReactYo.prop={};
ReactYo.idcount=0;
ReactYo.render=function(id,data){
  function getId(){
    var ret="_id_"+ReactYo.idcount;
    ReactYo.idcount++;
    return ret;
  }
  function escapeString(str){
if(str==null)return str;
var ev,ret,a=str.indexOf("{{"),b=str.indexOf("}}");
if(a==-1 || b==-1)return str;
ret=str.substring(0,a);
ev=str.substring(a+2,b);
ret+=eval(ev);
ev=str.substring(b+2);
ret+=ev;
return ret;
  }
  function createElement(elem,data,kid){
    if(elem==null)return "";
    if("children" in elem ==false || elem.children.length==0){
      var str=elem.innerHTML;
      if(kid in ReactYo.prop)str=ReactYo.prop[kid];
      else ReactYo.prop[kid]=str;
      return escapeString(str);
    }
    var i,len=elem.children.length;
    var li=[];
    li.push(React.Fragment);
    li.push({});
    for(i=0;i<len;i++){
      var pro={},id=null;
      if("id" in elem.children[i] && elem.children[i].id!="")id=elem.children[i].id;
      if(id!=null && data && id in data){
  pro=data[id];
          //println(JSON.stringify(pro));
      }
      if(id==null)id=getId();
      if(id)pro["id"]=id;
      var el=createElement(elem.children[i],data,id);
      if(el!=null && el!=""){
          li.push(React.createElement(elem.children[i].tagName.toLowerCase(),pro,el));
       }
      else{
          li.push(React.createElement(elem.children[i].tagName.toLowerCase(),pro));
      }
    }
    return React.createElement.apply(null,li);
  }
  if(id==null)return;
  var kid=null;
  var elem=document.querySelector(id);
  if("id" in elem)kid=elem.id;
  if(kid==null)kid=getId();
  var reactelem=createElement(elem,data,kid);
  ReactDOM.render(reactelem,elem);
}


//
// data
//


data={
  child2:{
    onClick:function(){onClick("sss")},
  },
  input1:{
    value:"134",
    onChange:function(e){onChange(e.target.value)},
    onBlur:function(e){onBlur(e.target.value)},
    className:"cls1",
  },
};


//
// functions
//

println=function(str)
{
alert(str);
}

onClick=function()
{
println("onClick()");
}

onChange=function(s)
{
  data.input1.value=s;
  ReactYo.render('#root3',data);
}

onBlur=function(s)
{
var str="onBlur(\"";
str+=s;
str+="\")";
//println(str);
console.log(str);
}

count=0;
getMsg=function(s)
{
var ret="message"+count;
count++;
return ret;
}

onTimeout=function()
{
  //println("onTimeout()");

  data.input1.className="cls2";
  data.input1.value="777";
  ReactYo.render('#root2',data);
  ReactYo.render('#root3',data);
  ReactYo.render('#root',data);
}



//
// render
//


println("React 16.12.0");

ReactYo.render('#root2',data);
ReactYo.render('#root',data);
ReactYo.render('#root3',data);

setTimeout(onTimeout,5000);
------------------------------


0 件のコメント:

コメントを投稿