How to mock global variable which holds React Native native module function - react-native

In App.js I have some thing like
Class App extends Component {
constructor(props){
super(props)
global.test = NativeModules.TestClass
}
}
And in Test class I am using it like
Class Test extends Component {
constructor(props){
super(props)
global.test.testFunction("Testing")
}
}
So how to mock global.test.testFunction for the above class

I suggest another approach for global function, variables. You can create a Utils class for each global functions, variables (constants or enums) and import the Utils wherever you need to use them.
Here is a very basic example for Utils Class:
Utils Class
export default class Utils {
static navigationRef = null;
static showAlert(title, desc) {
Alert.alert(title, desc);
}
}
USAGE:
import Utils from "./shared/utils"
// Example of static function
Utils.showAlert("Hello" "Alert Description")
// Example of static variable
Utils.navigationRef = this.props.navigation;

Related

Vue3 / How to pass data from mixin setup() to component

I would like to pass my object based on JavaScript class from mixin to component without reactivity. I use TypeScript, so I can't set the object to this of mixin without setting types in data(). But data() reactivity breaks some thing in my object.
mixin.js:
export default {
setup() {
const foo = new Foo()
return {
foo,
}
}
}
component.js:
import mixin from './mixin.js'
export default {
setup() {
// How can I get foo here?
}
}
Update 1
Yes, it is good solution for using only one foo instance for everywhere.
But how can I use different foo instances for each component?
Same as in JS classes:
class Mixin {
foo() {
// ...
}
}
class Component extends Mixin {
bar() {
this.foo()
}
}
mixin.js
export const foo = new Foo()
Import (and use) foo anywhere in your app, including any setup() function:
import { foo } from './path/to/mixin'
The above uses the same instance everywhere. If you want to use different instances of foo in each separate component, mixin.js:
export const useFoo = () => new Foo()
Anywhere else:
import { useFoo } from './path/to/mixin'
const foo = useFoo()
However, take note the second approach creates a new intance of Foo() every time useFoo() is called. So once you called it, you must use foo in that component.
Calling useFoo() multiple times in the same component will generate multiple instances, unlike how you'd use useStore(), for example.
But, I'm wondering, why do you need a mixin in the first place? Why not use:
const foo = new Foo()
...in the components where you need it?
What are you trying to achieve? And, more importantly, why?

Applying a class type to a property in state in react native

I created a class in react native.
import Author from "./authorDetails";
class MainFeedPost {
id;
description;
postImage;
author;
creationDateTime;
version;
status;
extra = {
likes,
shares,
comments
};
constructor() {
this.author = new Author();
}
}
export default MainFeedPost;
Now I want to set this as a type in one of my components state. I tried it like this an it is undefined.
import { MainFeedPost } from "../../models";
class SharePostScreen extends Component {
constructor(props) {
super(props);
this.state = {
post: MainFeedPost
};
}
doesn't this support in react native? I want to initialize the shape of my object with MainFeedPost class.
You told "as a type". If you want static type checking, you need something like flow.
If you wanna value in the state, you must place there an instance:
...
this.state = {
post: new MainFeedPost(),
};
...
UPD:
I got your point. Because of default export you need to use import MainFeedPost from "...", without braces.

RN Component syntax

Can anyone point a direction of the Component syntax using the latest React-Native init cmd? I don't recall ES6 class syntax quite like it.
export default class App extends Component<{}> {
}
Where, I've seen the following without brackets.
export default class App extends Component {
}
Thanks
Reference : https://reactjs.org/docs/components-and-props.html
class Example extends Component {
render() {
return <h1>Hello</h1>;
}
}
This is the ES6 way of defining components in react.

Aurelia: Dep. Injection on derived classes not possible? (or what am I doing wrong?!)

The scenario: I have two derived classes that both extend the ActionBase class as follows. I want to use DI for both derived classes. But both classes have different dependencies. That should be possible, right? So what am I doing wrong? In both cases the injected instances/modules are 'undefined'. Any help/hint appreciated.
/*
* Base class for Actions
*/
export class ActionBase {
type;
constructor(type) {
this.type = type;
}
}
/*
* Derived Class: InsertAction
*/
import {inject} from 'aurelia-framework';
import {ActionBase} from './ActionBase';
import {PomManager} from '../manager/PomManager';
#inject(PomManager)
export class InsertAction extends ActionBase {
pomManager;
constructor(pomManager) {
super("insert");
this.pomManager = pomManager;
console.log("[InsertAction:constructor] pomManager: ", this.pomManager); // undefined
}
}
/*
* Derived Class: RenderAction
*/
import {inject} from 'aurelia-framework';
import {ActionBase} from './ActionBase';
import {AnotherManager} from '../manager/AnotherManager';
#inject(AnotherManager)
export class RenderAction extends ActionBase {
anotherManager;
constructor(anotherManager) {
super("render");
this.anotherManager = anotherManager;
console.log("[RenderAction:constructor] anotherManager: ", this.anotherManager); // undefined
}
}
It is supported. Look at this working example where Action1 and Action2 extend BaseAction and each take different dependencies.
Here's an example: https://gist.run?id=0efabf77c649f41981dcde753fdc542c
app.js
import {inject} from 'aurelia-dependency-injection'
import {Action1, Action2} from './classes'
#inject(Action1, Action2)
export class App {
constructor(a1, a2){
this.message = "look at console output";
console.log("a1", a1.dep.constructor.name);
console.log("a2", a2.dep.constructor.name);
}
}
classes.js
import {inject} from 'aurelia-dependency-injection'
export class Action1Dependency {}
export class Action2Dependency {}
export class ActionBase{
}
#inject(Action1Dependency)
export class Action1 extends ActionBase{
constructor(dep){
super();
this.dep = dep;
}
}
#inject(Action2Dependency)
export class Action2 extends ActionBase{
constructor(dep){
super();
this.dep = dep;
}
}

Can typescript external modules have circular dependencies?

It looks like this is not allowed. requireJS is throwing an error on the following (this post is different as it was resolved with internal modules):
element.ts:
import runProperties = require('./run-properties');
export class Element {
public static factory (element : IElement) : Element {
switch (element.type) {
case TYPE.RUN_PROPERTIES :
return new runProperties.RunProperties().deserialize(<runProperties.IRunProperties>element);
}
return null;
}
}
run-properties.ts:
import element = require('./element');
export class RunProperties extends element.Element implements IRunProperties {
}
No, modules can't have circular dependencies unless they are in the same file. Each file is being processed in sequence, synchronously, so the full file definition (including all of the exports for example) hasn't been completed when it goes to second file, which immediately tries to require/reference the first file, and so on.
Normally, you can break a circular dependency by introducing an interface or base class into a common definition file(s) (basically interfaces only) and having the other files use that as a common "interface" rather than directly referencing the classes. This is a typical pattern in many platforms.
I have same issue, I was able to fix it by creating factory class that allows registration of child classes and used Generics for instantiation.
Reference: https://www.typescriptlang.org/docs/handbook/generics.html#using-class-types-in-generics
See sample code below:
Base Class (abstract.control.ts)
export type AbstracControlOptions = {
key?:string;
}
export abstract class AbstractControl {
key:string;
constructor(options:AbstracControlOptions){
this.key = options.key;
}
}
Parent Class (container.ts)
import { AbstractControl, AbstracControlOptions } from './abstract.control';
import { Factory } from './factory';
export { AbstracControlOptions };
export abstract class Container extends AbstractControl {
children: AbstractControl[] = [];
constructor(options: AbstracControlOptions) {
super(options);
}
addChild(options: { type: string }) {
var Control:any = Factory.ControlMap[options.type];
if (Control) {
this.children.push(Factory.create(Control, options));
}
}
}
I don't have to import the child classes any more, because I'm using factory.ts to instantiate the child classes.
Factory Class(factory.ts)
import {AbstractControl, AbstracControlOptions} from './abstract.control';
type ControlMap<T extends AbstractControl> = {
[type:string]:T
};
export class Factory{
static ControlMap: ControlMap<any> = {};
static create<T extends AbstractControl>(c: { new ({}): T; }, options: AbstracControlOptions): T {
return new c(options);
}
}
Although class constructor seems to be called at c: { new ({}): T } but it does not actually calls it. But gets the reference to the constructor via new operator. The parameter {} to the constructor in my case is required because the base class AbstractControl requires it.
(1) Child Class(layout.ts)
import { Factory } from './factory';
import { Container, AbstracControlOptions } from './container';
export type LayoutlOptions = AbstracControlOptions & {
type:"layout";
}
export class Layout extends Container {
type: string = "layout";
constructor(options:LayoutlOptions) {
super(options);
}
}
Factory.ControlMap["layout"] = Layout;
(2) Child Class(repeater.ts)
import { Factory } from './factory'
import { Container, AbstracControlOptions } from './container';
export type RepeaterOptions = AbstracControlOptions & {
type: "repeater";
}
export class Repeater extends Container {
type: string = "repeater";
constructor(options:RepeaterOptions) {
super(options);
}
}
Factory.ControlMap["repeater"] = Repeater;