Implement a simple react native

Aaaaaaaaaaayou 2021-05-04 18:53:16
implement simple react native


introduction

Last time , We succeeded in putting React Apply rendering to Canvas above . Today we are more ambitious , To achieve a simple React Native, We call him Extremely Tiny React Native. The final effect we achieved is shown in the figure below :

demo.gif

The corresponding React The code is as follows :

import React from 'react'
import {View, Text} from './react-native'
import {useEffect, useState, useRef} from 'react'
const W = 100
const innerW = 50
function useUpdate() {
const [_, _update] = useState()
return () => _update(Math.random())
}
function App() {
const x = useRef(0)
const y = useRef(0)
const update = useUpdate()
const animate = () => {
setTimeout(() => {
if (y.current === 0 && x.current < W - innerW) {
x.current += 1
} else if (x.current >= W - innerW && y.current < W - innerW) {
y.current += 1
} else if (y.current >= W - innerW && x.current > 0) {
x.current -= 1
} else {
y.current -= 1
}
update()
animate()
}, 50)
}
useEffect(() => {
animate()
}, [])
return (
<>
<Text x={50} y={50} w={W} h={W} r={0} g={0} b={0} a={1} fontSize={16}>
Tiny React Native
</Text>
<View x={50} y={100} w={W} h={W} r={255} g={0} b={0} a={1}>
<View
x={x.current}
y={y.current}
w={innerW}
h={innerW}
r={0}
g={255}
b={0}
a={1}>
<Text
x={18}
y={13}
w={50}
h={50}
r={0}
g={0}
b={255}
a={1}
fontSize={20}>
S
</Text>
</View>
</View>
</>
)
}
 Copy code 

Pre knowledge preparation

Achieve this Extremely Tiny React Native The two core knowledge required are :

  • JavaScriptCore
  • React Custom Renderer

among React Custom Renderer We've talked about that before , See React Source code analysis Custom Renderer, So here we just briefly introduce JavaScriptCore.

JavaScriptCore

JavaScriptCore ( hereinafter referred to as JSCore) yes iOS Upper JavaScript( hereinafter referred to as JS) Execution engine , It builds up Objective-C( hereinafter referred to as OC) and JS A bridge between two languages . Let's take an example to see its basic usage :

Patients with a : perform JS Code :

JSContext *jsCtx = [[JSContext alloc] init];
JSValue *value = [jsCtx evaluateScript:@"function hi(){ return 'hi' }; hi()"];
NSLog(@"%@", value); // hi
 Copy code 

Example 2 :JS call Native Methods :

jsCtx[@"log"] = ^(NSString *msg){
NSLog(@"js:msg:%@",msg);
};
[jsCtx evaluateScript:@"log('hello,i am js side')"];
 Copy code 

Above , We are JSContext Object has a log After the method ,JS The method can be called directly from the code .

Example 3 :JS Use Native Objects in the :

  1. First, customize a protocol JSPersonProtocol Inherited from JSExprot, And define what needs to be exposed to JS Properties and methods of :
#import <Foundation/Foundation.h>
#import <JavaScriptCore/JavaScriptCore.h>
NS_ASSUME_NONNULL_BEGIN
// Define an agreement , It can be understood as an interface 
@protocol JSPersonProtocol <JSExport>
- (NSString *)whatYouName;
@end
 Copy code 
  1. Create a new one Person object , Implementation protocols and methods :
// Inherit NSObject, Realization JSPersonProtocol agreement 
@interface Person : NSObject<JSPersonProtocol>
@property (nonatomic, copy)NSString *name;
- (NSString *)whatYouName;
@end
NS_ASSUME_NONNULL_END
 Copy code 
#import "Person.h"
@implementation Person
-(NSString *)whatYouName {
return @"Ayou";
}
@end
 Copy code 
  1. Use :
Person *p = [[Person alloc]init];
jsCtx[@"person"] = p;
JSValue *name = [jsCtx evaluateScript:@"person.whatYouName()"];
NSLog(@"%@",name); // Ayou
 Copy code 

Realization principle

image.png

stay React Source code analysis Custom Renderer Introduced in Custom Renderer You need to implement some host related interfaces , Such as :createInstanceappendChild etc. .

In our Extremely Tiny React Native in , These interfaces are all through JSCore towards Native send out JSON Formatted message , The real operation is Native Side to side . The implementation of message delivery has been described in example 3 above , Just post the code here :

@protocol BridgeProtocol <JSExport>
- (void) send:(NSString *)msg;
@end
@interface Bridge : NSObject<BridgeProtocol>
- (void) send:(NSString *)msg;
@end
NS_ASSUME_NONNULL_END
 Copy code 
- (void) send:(NSString *)msg {
// serialize json character string 
NSError *jsonError;
id jsonObj = [NSJSONSerialization JSONObjectWithData:[msg dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&jsonError];
NSString *operation = [jsonObj objectForKey:@"operation"];
...
}
 Copy code 
self.jsContext[@"RNBridge"] = [[Bridge alloc] initWithRootViewController:self];
 Copy code 

For example, call createInstance when ,JS Will inform Native The current operation of the side is createView( or createText), That is, it needs to be in Native Create a RNView( or RNText) The object of :

// RNView
[self.eleDict setObject:[[RNView alloc] init:props] forKey:_id];
// RNText
[self.eleDict setObject:[[RNText alloc] init:props] forKey:_id];
 Copy code 

A unique identifier is also assigned to the object id, It is convenient for other subsequent operations through the id To find the corresponding object , And the id It will be attached to FiberNode Of stateNode Above attributes ( This step is React For us ).

When calling appendChild when ,React It will pass in parent and child( Notice the parent and child That's what I mentioned earlier id):

appendChild: function (parent, child) {
RNBridge.send(JSON.stringify({operation: 'appendChild', parent, child}))
},
 Copy code 

The rest of the interfaces are implemented step by step , The complete code can be found in tiny-react-native.

summary

utilize JavaScriptCore and React Custom Renderer, We have achieved a React Native, But at the moment it's very simple , The following functions can be further enhanced in the future :

  • Support style attribute
  • Support Reload The function of
  • Support Flexbox Layout

Welcome to the official account 「 Front end tour 」, Let's travel together in the ocean of front end .

版权声明
本文为[Aaaaaaaaaaayou]所创,转载请带上原文链接,感谢
https://qdmana.com/2021/05/20210504184939101y.html

  1. Gallop workflow engine design series 01 process element design
  2. VUE移动端音乐APP学习【十六】:播放器歌词显示开发
  3. Vue Mobile Music App learning [16]: player lyrics display development
  4. jquery cookie
  5. jquery cookie
  6. 体面编码之JavaScript
  7. JavaScript for decent coding
  8. React17 系统精讲 结合TS打造旅游电商平台
  9. React17 system combined with TS to build tourism e-commerce platform
  10. 2021-05-04 hot news
  11. HttpSession对象与Cooike的关系 以及 Cookie对象构造函数问题
  12. gRPC-Web:替代REST的gRPC的Javascript库包
  13. The relationship between httpsession object and cooike and the construction of cookie object
  14. Grpc Web: a JavaScript library package to replace rest grpc
  15. Building reactive rest API with Java - kalpa Senanayake
  16. PDF转HTML工具——用springboot包装pdf2htmlEX命令行工具
  17. Pdf to HTML tool -- Wrapping pdf2htmlex command line tool with springboot
  18. PDF转HTML工具——用springboot包装pdf2htmlEX命令行工具
  19. Pdf to HTML tool -- Wrapping pdf2htmlex command line tool with springboot
  20. Vue.js比jQuery更容易学习
  21. Node.js的Reactor模式 与异步编程
  22. Vue. JS is easier to learn than jQuery
  23. Reactor mode of node.js and asynchronous programming
  24. 详解JavaScript中的正则表达式
  25. Explain regular expressions in JavaScript
  26. 详解JavaScript中的正则表达式
  27. Explain regular expressions in JavaScript
  28. JS: closure
  29. Write your own promise in promises / A + specification
  30. Analysis of the core mechanism of webpack from loader, plugin to egg
  31. On the import and export of webpack
  32. Interpretation of lodash source code (2)
  33. Hexo series (5) writing articles
  34. 有人用过JMeter或用HttpUnit写过测试吗????
  35. Has anyone ever used JMeter or written tests in httpUnit????
  36. JavaScript异步编程4——Promise错误处理
  37. Leetcode 1846. Reduce and rearrange the largest element of an array
  38. JavaScript asynchronous programming 4 -- promise error handling
  39. SQLite是一种经典的无服务器Serverless
  40. 通过Spring Boot Webflux实现Reactor Kafka
  41. SQLite is a classic server less
  42. Realization of reactor Kafka through spring boot Webflux
  43. Focus on the basic knowledge of JS
  44. Node.js与Spring Boot比较? - Ryan Gleason
  45. Compare node.js with spring boot- Ryan Gleason
  46. 「HTML+CSS」自定义加载动画【049】
  47. 「HTML+CSS」自定义加载动画【048】
  48. 「HTML+CSS」--自定义加载动画【047】
  49. "HTML + CSS" custom loading animation [049]
  50. "HTML + CSS" custom loading animation [048]
  51. "HTML + CSS" -- custom loading animation [047]
  52. 使用Akka实现Reactive DDD
  53. Prototype与JQuery对比
  54. Using akka to realize reactive DDD
  55. Comparison between prototype and jquery
  56. Please elaborate the diff algorithm of Vue
  57. On the combination of ecarts and Baidu map, in the Intranet environment to develop offline map, to achieve point, line, range value.
  58. 使用Slonik框架基于Node.js和PostgreSQL处理大量数据
  59. Using slonik framework to process large amount of data based on node.js and PostgreSQL
  60. Netflix使用React制作高性能电视用户界面