Skip to content

Commit 22a37bd

Browse files
Update React.php
1 parent 956fc68 commit 22a37bd

File tree

1 file changed

+24
-12
lines changed

1 file changed

+24
-12
lines changed

React.php

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,23 @@
44

55
abstract class Component{
66
private static $isTagsSet = false;
7-
private static $htmlTags = ['div','p','img','h1','h2','h3','h4','h5','h6','iframe','article', 'form','input','textarea','select','option', 'link', 'script', 'button'];
8-
private static $hasNoChild = ['img', 'link', 'input'];
7+
private static $htmlTags = ['div','p','img','h1','h2','h3','h4','h5','h6','iframe','article', 'form','input','textarea','select','option', 'link', 'script', 'button', 'nav', 'title', 'meta'];
8+
private static $hasNoChild = ['img', 'link', 'input', 'meta'];
99
private const tagNameSpace= 'React\Tag';
1010
private static $counter = 1;
1111
protected $id = '';
1212
protected $state = [];
13+
private static $states = [];
1314

1415
private function setTags(){
16+
@ob_start();
1517
foreach(self::$htmlTags as $el){
1618
eval("namespace ". self::tagNameSpace ."; class $el extends \React\Component{}");
1719
}
1820
self::$isTagsSet = true;
1921

2022
//script tag to setup setState function
21-
echo new \React\Tag\script('const phpReact={setState:function(t,e){var n=document.getElementById(t);if(n){var a=new XMLHttpRequest;a.onreadystatechange=function(){4==this.readyState&&200==this.status&&(n.outerHTML=this.responseText)},a.open("POST",location.href,!0),a.setRequestHeader("Content-type","application/x-www-form-urlencoded"),a.send("phpreact="+JSON.stringify({id:t,state:e}))}}};');
23+
echo new \React\Tag\script('const phpReact={setState:function(t,e,n){var a=document.getElementById(t);if(a){var r=this.getState(t);"function"==typeof e&&(e=e(r));var o=new XMLHttpRequest;o.onreadystatechange=function(){4==this.readyState&&200==this.status&&(a.outerHTML=this.responseText,"function"==typeof n&&n())},o.open("POST",location.href,!0),o.setRequestHeader("Content-type","application/x-www-form-urlencoded"),o.send("phpreact="+JSON.stringify({id:t,state:e,prevState:r}))}},getState:function(t){try{var e=document.getElementById(t);return JSON.parse(e.getAttribute("prevstate"))}catch(t){return{}}}};');
2224
}
2325

2426
private function getTagName(){
@@ -33,7 +35,7 @@ private function hasNoChild(){
3335

3436
static function registerTag($tags, $hasNoChild = false){
3537
self::$htmlTags= array_unique(array_merge(self::$htmlTags, (array)$tags));
36-
if($hasNoChild) self::setHasNoChild($tags);
38+
if($hasNoChild) $this->setHasNoChild($tags);
3739
}
3840

3941
static function setHasNoChild($tags){
@@ -43,6 +45,10 @@ static function setHasNoChild($tags){
4345
function render(){
4446
if(!$this->isHtmlTage()) return '';
4547

48+
//save states in dom attribute [prevState]
49+
if($this->props->id && self::$states[$this->props->id])
50+
$this->props->prevState = json_encode(self::$states[$this->props->id]);
51+
4652
$tag = $this->getTagName();
4753
$attr = [];
4854
foreach($this->props as $k=> $v){ $attr[] = $k.'="'.htmlspecialchars($v).'"'; }
@@ -62,30 +68,36 @@ function __construct($children = [], $props = []){
6268
if(!self::$isTagsSet) $this->setTags();
6369
$hasNoChild = $this->hasNoChild();
6470
$this->setId();
65-
$this->setStateListener();
71+
72+
if(!is_array($children)) $children = [$children];
6673

6774
//set properties
6875
$this->props = (object)($hasNoChild ? $children : $props);
69-
$this->children = (array)($hasNoChild ? [] : $children);
76+
$this->children = $hasNoChild ? [] : $children;
77+
$this->state = (object)$this->state;
78+
79+
//listen to state change
80+
$this->setStateListener();
7081
}
7182

7283
function componentDidUpdate($oldState, $currentState){}
7384

7485
private function setId(){
7586
if($this->isHtmlTage()) return;
76-
$this->id = md5(self::$counter);
87+
$this->id = md5(self::$counter); //generate id
88+
self::$states[$this->id] = $this->state; //save all states by id
7789
self::$counter++;
7890
}
7991

8092
private function setStateListener(){
8193
if(empty($_POST['phpreact'])) return;
8294
$post = json_decode($_POST['phpreact']);
83-
if($post->id != $this->id) return;
84-
@ob_start();
85-
@ob_end_clean();
86-
$oldState = $this->state;
87-
$this->state = array_merge($oldState, (array)$post->state);
95+
if(!$post || $post->id != $this->id) return;
96+
$oldState = $post->prevState;
97+
$this->state = (object)array_merge((array)$oldState, (array)$post->state);
98+
self::$states[$this->id] = $this->state;
8899
$this->componentDidUpdate($oldState, $this->state);
100+
@ob_end_clean();
89101
die($this);
90102
}
91103
}

0 commit comments

Comments
 (0)