How to call a function from another class React-native - reactjs

I am trying to call a function from another class it throws an error getValue is not a function. i dont want to use static. I hope there's a solution for it. here's my code
import React, { Component } from "react";
import SecondClass from "./main"
export default class A extends Component{
constructor (props) {
super(props)
onPress = ()=>{
getValue()
}
}
//SecondClass
export default class SecondClass extends Component{
constructor (props) {
super(props)
}
getValues = () => {
alert("Hello")
}
}

I think you need to define the function in the A and then pass the function in the SecondClass component as a prop...

https://www.npmjs.com/package/react-native-simple-events
You can use this library here you can register your function and can trigger from anywhere in app.
For register your function use on("eventID", "listenerID", ()=>{//call getValues}) in class SecondClass
For Trigger your function use trigger("eventID", eventData) in class A
After that remove the listener by using remove("eventID", "listenerID") from class SecondClass

You cannot expect that you can simply call some function in another class because you imported that class. The React way of doing this would be to pass the function as a prop if these are parent-child components. If not, I would highly recommend extracting the common function out from both classes and call them separately.
From the comments, other users have also recommended using static function if you absolutely want to couple the function to Second class.
My main objective is when user press the button then it should call the method from another class and return Hello. Then later i want to set some properties which i not possible in static function. So thats why i dont want to use static function
From your sample code it looks like Second is a React component ? If this class was made to encapsulate certain behavior then I would recommend turning it into a plain javascript class and then instantiate/use wherever necessary.

Related

Best practice for specifiying component interface in react.js?

I wrote a component Foo in React.js (its parameter "interface" consists of a single parameter text; there are more parameters in my real code):
import React from 'react';
export default class Foo extends React.Component {
constructor(props){
super(props);
}
render(){
return <div>{this.props.text}</div>;
}
}
and I thought I could improve the code by modifying the property access as:
import React from 'react';
export default class Foo extends React.Component {
constructor(props){
super(props)
this._text = props.text
}
render(){
return <div>{this._text}</div>;
}
}
This would give me the benefits that
I can immediately see what properties are supported by having a look at the constructor.
The code that applies the properties gets shorter/better to read.
However, this destroys the update workflow for the property. In a parent component I use Foo like
<Foo text={this.state.parentText}/>
and
this.setState({parentText: "new text"})
does not trigger an update of the text in Foo any more. The constructor of Foo is only called once and therefore, the private variable this._text is not updated on property changes.
=> Using extra private properties to modify the parameter access turned out to be a bad idea.
=> What would you recommend to have a clear interface for the component without breaking the update workflow?
Some ideas:
a) List all used properties at the start of render (and componentDidUpdate)
render(){
const text = this.props.text;
return <div>{text}</div>;
}
b) Create a getter for each property and put them directly under the constructor, for example
get _text(){
return this.props.text;
}
c) (Only for shorter access.) Try to avoid class components. With function components there is direct access with props.text instead of this.props.text. Or, as a workaround, inherit from a custom component class that passes props argument to render:
render_props(props){
...
}
(Why doesn't react pass this.props as an argument to render by default?)
d) Document the supported properties in a doc string
=> If you know a better option / some standard / best practice, please let me know.
Also tried but failed:
I tried to use state in the child component, with the hope that it would be automatically updated on updates of the parent state:
import React from 'react';
export default class Foo extends React.Component {
constructor(props){
super(props)
this.state = {
text: props.text
}
}
render(){
return <div>{this.state.text}</div>;
}
}
However, this also breaks the update workflow. Using this.state only seems to make sense in the parent component.
Related:
Can I update a component's props in React.js?
https://github.com/vasanthk/react-bits/blob/master/anti-patterns/01.props-in-initial-state.md
Related topic:
How to interact with third party libraries using function components?
https://reactjs.org/docs/integrating-with-other-libraries.html
How do I use/include third party libraries in react?
Integrating React with Other Libraries
Use function components for React >= 16.8, also see recommendation at
https://www.w3schools.com/react/react_class.asp
Use useState hooks instead of setState. This is the modern way to write React, and gives you a simpler way to access state (foo.text, foo.setText). https://reactjs.org/docs/hooks-state.html
Typescript would help with docs (type props = { text: string }), but I also would like the answer for d) (your question is several questions I think).
Use props.text directly, instead of using extra shortcut variable const text = props.text suggested by option a). This way, you don't have a list of all available properties on top of the component function. However, using a consistent props. prefix makes it easier to spot the injected variables in the react code. If there is a huge number of properties and its hard to identify them, try to improve modularization.
JavaScript example code:
Child component Foo:
import React from 'react';
export default function Foo(props){
return <div>{props.text}</div>;
}
}
Parent component:
import React, { useState } from 'react';
import Froo from './foo';
export default function Parent(){
const [parentText, setParentText] = useState('Hello world');
return <Foo text={parentText}/>;
}

React-Redux-Class extends value #<Object> is not a constructor or null

Class extends value # is not a constructor or null
Error shows up when tried Inheriting a Parent Class which is binded with react-redux "connect" ->
Redux
const mapStateToProps=(state)=>({
.....
});
const mapDispatchToProps=(dispatch)=>{
return {
paymentOver:()=>dispatch(paymentClose()),
}
}
export {
mapStateToProps,mapDispatchToProps
}
Parent Class
import { connect } from "react-redux";
import { mapStateToProps,mapDispatchToProps } from "../../State Management/MappingStates";
Class MainContainer extends Component{
componentDidMount(){
this.props.paymentOver(); //redux action
}
}
export default connect( mapStateToProps,mapDispatchToProps )( MainContainer )
Sub Class
import MainContainer from './MainContainer';
Class Sub extends MainContainer{ //Error showing at this line- Class extends value #<Object> is not a
//constructor or null
render(){
return ......
}
}
export default Sub
Afaik, connected components are function components, so you cannot extends them.
Either way, even if it were a class component, it would be a new Component that just rendered your original class component. So neither way, you could extend this.
In general: in React, you should never extend components - even class components, but use other patterns like higher order components or composition.
Also, the whole ecosystem is shifting to function components for two years now. Unless you have a very good reason to (like maintaining a very legacy code base), you probably should not write class components any more.
That is also the recommendation of the redux style guide: use hooks (useSelector and useDispatch) and function components over connect and class components.
If you are just learning react & redux, you are probably following very outdated sources. For Redux, pleasee look at the official tutorials at https://redux.js.org/tutorials/index

Typescript extend React.Component

#tl;dr
I want to extend a React Component without using HOC / Providers in Typescript
OK, so here's the deal...
At my work place we used to work with Vue and plain JS... then we decided to migrate to React with Typescript...
Tecnologies we use:
- React
- Typescript
- Redux
- Redux-Saga
The thing is, back in Vue, we could declare something like:
Vue.use(Auth)
and on every .vue file, inside the script tag we could call something like:
this.$auth
and have access to authorizatin methods.
What I want to do is... create an extension of ReactComponent where I already created some methods that most of my Component will use... something like:
auth // Check if user is authenticated, and if so, get the User Info
route // Give me the current route, with query params, redirects, etc...
Those were the only two I could think off here now.
I want to have in my .ts file something like this:
interface MyProps {
route: any // don't remember the correct Type
}
class MyComponent<T,S = {},SS = {}> extends React.Component<T,S,SS> {
$route = () => {
this.props.route
}
}
export default withRouter(MyComponent)
and have it being called in my application like this:
inteface AnotherProps {
}
class AnotherComponent extends MyComponent<AnotherProps> {
render() {
if(this.$route().location.pathname == "/") {
return <div>Root</div>
} else {
return <div>Not Root</div>
}
}
}
What I have tried so far
HOC (High Order Components)
I could achieve what I want using HOC, but the thing is... if possible, I would like 2 things.
To have this new properties being store at this and not this.props, and if that's possible using HOC, i don't know how
With HOC, I would also need to import the base Props, something like this:
import BaseProps from Outterspace;
inteface AnotherProps extends BaseProps{
}
and I want the logic inside the MyComponent and AnotherComponent to be as independent to each other as possible...
Providers
Same as HOC, I would need to pass the properties I want as props, and would need to extend my props interface.
[EDIT]
Decorators
Someone said in the comments that I could try using Decoratos, and while I did read the docs and it sounded promising... the last line of the Docs kinda worries me..
NOTE Decorator metadata is an experimental feature and may introduce breaking changes in future releases.
Thank you so much for reading this far ^^
If you are using typescript then you can create decorators.
You can call the decorator on top of your class and add the property.
#YourAuthDecorator({
'propertiesForconfiguration': 'value'
})
export class ReactClass extends ReactComponent {}
Example:
function abc() {
return {};
}
export function Auth() {
console.log("-- decorator function invoked --");
return function (constructor: Function){
console.log(constructor, 'called');
constructor.prototype.$auth = abc();
}
}
class Sample {
public prop = 'sample'
}
#Auth()
export class Content extends Sample {
}
export const a = new Content();
It will be the decorator's functionality to append various properties the to this instance providing you access to various functions/properties like auth
You can read more about decorators here.
https://www.typescriptlang.org/docs/handbook/decorators.html

Is it necessary to create a render function in a react native application?

I have a list of functions that use different react-native's built-in features, I want to create a react-native class that uses those features and only use its functions and those functions will not return anything
What I have already done is returned null from my render function.
but in this case I have to create use refs to call my functions
what I'm trying to achieve is this
export default class Wrapper extends Component{}
and in my screens I want to do this
export default class MyScreen extends Wrapper{
}
or may be
export default class MyScreen extends Component{
componentDidMount(){
Wrapper.myFunction()
}
}
Wrapper.myFuntion() works with all the react native's feature but doesn't render anything in view and only used for data manipulation.
Why dont you create a class which just imports the React features you want, then that class can be called with the functions you want?
If you don't want to run through the lifecycle of React, then don't extend off of a React Component.
For example, create a class:
export class ReactFunctions {
constructor (stuff : any) {
//constructor code
}
public reactFunction1 () {
//react stuff....
}
}
And import it when you need it....
import {ReactFunctions} from ....
Following on from that, I create 'micro-services' and helper classes which don't necessarily have React based functions in. You can separate out common functionality into common modules.

Code sharing between React ES6 Classes

I'm struggling to dry up a few functions i'm using accross several of my component classes. Mixins are a no-go and I'm struggling to understand what alternative I'm supposed to use. Setting the code up as a module seems promising, but I don't understand how to package it so I can use it to extend several different class.
Say I have:
class functionsToShare {
thingToDo(){
//do a thing
}
}
export default functionsToShare;
I'm assuming in my component class I'd want something like:
import React from 'react';
import functionsToShare from 'some/path'
class SomeComponent extends React.Component{
constructor(props){
super(props);
}
render(){
return (
);
}
}
export SomeComponent
But how do I use the shared class to extend my component? If I declared it inthe class declaration likemy componenet is delcared to extend React.Component that would defeat the reusability... Is there an alternate way I should be looking at?
You can create your shared functions file as a file with several functions that you need to use, each function being exported as a named export. Like this:
export function thingToDo() {
...
}
export function getUserByEmail(email) {
...
}
Save this file as functionsToShare.js, for example.
Then in each React component class (or anywhere else) you can import that functions, just ones you need by:
import {thingToDo} from "./functionsToShare"; // import a function
thingToDo(); // call function
or all of them by:
import * as somename from "./functionsToShare"; // import all functions from that file
somename.thingToDo(); // call specific function

Resources