Can i update Context API state in javascript class? - javascript

I have a Bluetooth class and listener method. I want to update my state in Bluetooth class and i will show in functional component.
JavaScript Class
import React, { Component } from "react";
import { MySampleContext } from "../../contexts/MySampleContext";
export class BluetoothClass extends Component {
static contextType = MySampleContext;
sampleBluetoothListener(value){
this.context.updateMyState(value);
}
}
This is my error.
TypeError: undefined is not an object (evaluating 'this.context.updateMyState')

Yes you can, you can pass data down to your component tree using Context API.
// Context file
import React from 'react';
const FormContext = React.createContext();
export default FormContext;
// Parent Class Component
import FormContext from "../context";
class ParentClass extends Component {
state = { name: "John Doe" };
render() {
return (
<FormContext.Provider value={this.state.name}>
<ChildClass />
</FormContext.Provider>
);
}
}
// Child Class Component
import FormContext from "../context";
class ChildClass extends Component {
render() {
return (
<FormContext.Consumer>
{(context) => {
console.log(context);
}}
</FormContext.Consumer>
);
}
}
The value prop in the context API takes an object, in which you could add a method that changes your state and pass it down to your component tree.
I advice you to take a quick look at the official Context API docs by React for a better understanding.

Thanks for all answers. But i mean pure "javascript class" not component, without rendering and react hooks is component based. Finally i solve problem with call back functions.

Related

How to create an element and use its ref to append child elements in react?

I'm trying to create a html element on a parent component on react and access that component div inside a child component, then I can append new elements in the div from the child component.
After many attempts I wasn't able to fix props.canvasDivElement.current = null on the child constructor.
I've tried to do this using REF and without refs... No luck so far.
Any ideas?
The parent component looks like:
import React from "react";
import ReactViewer from "../ReactViewer/ReactViewer";
export default class CanvasWrapper extends React.Component {
private _divElement: React.RefObject<HTMLDivElement>;
constructor(props: any) {
super(props);
this._divElement = React.createRef<HTMLDivElement>();
}
render() {
return (
<div>
<ReactViewer canvasDivElement={this._divElement}></ReactViewer>
</div>
);
}
}
The child component:
import React from "react";
type ReactViewerState = {
};
type ReactViewerProps = {
canvasDivElement: React.RefObject<HTMLDivElement>;
};
export default class ReactViewer extends React.Component<ReactViewerProps, ReactViewerState> {
constructor(props: ReactViewerProps, state: ReactViewerState) {
super(props, state);
const newElement = document.createElement('span');
newElement.innerText = 'element';
props.canvasDivElement.current!.appendChild(newElement); //current is null
}
render() {
return (
<div ref={this.props.canvasDivElement} />
);
}
}
Rookie mistake, the element will always be null until it renders.
I've changed the line bellow to the componentDidMount event:
props.canvasDivElement.current!.appendChild(newElement);
It looks like you are trying to circumvent the basic principles of React to solve a problem that React provides other tools for. The React way of communicating between a child and a parent is to pass a callback function to the child. Then the child calls the callback to signal to the parent to update its children.

How to get React Js Child Component Reference in Parent Component While Using Apollo Client GraphQL

I have two react components the child component uses Apollo client for GraphQL which wraps the child component as higher order component. I want to access the child class method using reference to execute child method in parent class but when I use ref I get Graphql object instead of react child component. My code sample looks like this.
Note:
this question is not a duplicate of
React js change child component's state from parent component
OR
Access child state of child from parent component in react
Because
They don't use GraphQL Apollo Client)
Parent Component
import React, {Component} from 'react';
import "./Child";
class Parent extends Component{
state={
};
executeSomeChildFunction = () =>{
/* console.log(this.myChild); */
this.myChild.childFunction();
};
render(){
return(
<div>
<button onclick={this.executeSomeChildFunction}>
Click To Execute Child Function
</button>
<Child ref={el=> this.myChild =el} />
</div>
);
};
}
export default Parent;
Child Component
import React, {Component} from 'react';
const myQuery = `query DriversQuery() {
drivers: {
edges{
node{
id
pk
firstName
lastName
}
}
}
}`;
class Child extends Component{
state={
};
childFunction = () => {
alert("I am a child function");
};
render(){
return(
<div>Replace this div with your code!</div>
);
};
}
export default gql(myQuery, {/*some options*/})(Child);
What I Get as Output
When I console.log(this.myChild); I get a graphql object like this.
Expected Output
I want to get Child Element Reference. So that When I console.log(this.myChild); I should get Child component object.

how to create a class and another classes extends that class in react js

I am a beginner in react js, before react I was working with angular2 and backbone,and now my problem is I want to create a class such that all of my requests send from this class,like this:
class Ext {
get(url){
$.ajax({
url : url,
success : function(res){},
and ......
});
}
}
in my another component that use from my Ext function :
export default Ext;
import React from 'react';
import {render} from 'react-dom';
import {Ext} from "./module/Ext"
class App extends React.Component {
constructor(props) {
super(props);
/// Ext.get();
}
render () {
return(
<p> Hello React!</p>
);
}
}
render(<App/>, document.getElementById('app'));
how to extends from Ext ??? what is the best way ?
If your get(url) method is something general, it would be wise to have it as part of a separate module, then import and use it in any component you would like.
If, on the other hand, you want to implement a functionality right into a react component, the new ES2015 way of doing it would be by using Composition.
You first create what's called a HOC (Higher order component), which basically is just a function that takes an existing component and returns another component that wraps it. It encapsulates your component and gives it functionality you want, like with mixins but by using composition instead.
So your example would look like something like this:
import React from 'react';
export default const Ext = (Component) => class extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
let result = this.get('some_url').bind(this)
this.setState({ result })
}
get(url) {
$.ajax({
url : url,
success : function(res){
return res;
}
});
}
render() {
// pass new properties to wrapped component
return <Component {...this.props} {...this.state} />
}
};
Then you can just create a stateless functional component and wrap it with the HOC:
import React from 'react';
import Ext from './module/Ext';
class App {
render () {
return <p>{this.result}</p>;
}
}
export default Ext(App); // Enhanced Component
Or using ES7 decorator syntax:
import { Component } from 'react';
import Ext from './module/Ext';
#Ext
export default class App extends Component {
render () {
return <p>{this.result}</p>;
}
}
You can read this post for more details: http://egorsmirnov.me/2015/09/30/react-and-es6-part4.html

ReactJs / Javascript - Can a HOC read the parameter component's props?

I have a Higher Order Component that receives another component as a parameter:
HOC
export default function HOC(Comp) {
return class extends Component {
doSomething() {
const temp = // the Comp's clientId prop???
}
........
}
}
Sub Component
#HOC
export default class SubComponent extends Component {
.....
static proptypes = {
clientId: PropTypes.string.isRequired
};
.......
}
Question:
Is it possible in the scenario above for the HOC to be aware of SubComponent's clientId property in its arguements and if so, how can I make the HOC aware of it for my doSomething function?
Since it's really the HOC that receives the props (or rather the component the function returns), you can just access them with this.props:
const temp = this.props.clientId;

FindDOMNode flux/alt store

I'm trying to access a dom node from a store (using alt) in order to animate using velocity.js, however am only getting 'cannot read property of undefined'. Is it possible to use findDOMNode from an alt/flux store?
import React from 'react'
import alt from '../_alt';
import Actions from '../actions/actions';
import Velocity from 'velocity-animate/velocity';
import Body from '../modules/level_1/body/body1'
class Store {
constructor(){
this.bindListeners({
menuToggle: Actions.MENU_TOGGLE
});
this.menuStatus = false
}
menuToggle(){
if (!this.menuStatus){
this.menuStatus = true;
Velocity(React.findDOMNode(Body.refs.wrap),({ width: '50px' }), 50)
} else {
this.menuStatus = false;
}
}
}
export default alt.createStore(Store, 'Store');
Component:
import React from 'react';
import connectToStores from 'alt/utils/connectToStores';
import Store from '../../../stores/store'
import Actions from '../../../actions/actions';
import Styles from './body1.css';
import Hero from '../../objects/hero/full_width'
let image = ['../../../../assets/full_width1.jpg', 'image']
#connectToStores
export default class Body extends React.Component {
static getStores(){
return [Store];
}
static getPropsFromStores(){
return Store.getState();
}
render(){
return (
<div ref='wrap'>
<Hero content={image} />
</div>
);
}
}
Body is a react class, which does not have refs.
What you need is a react element (an instance of a react class) which is the "this" inside of render, componentDidMount, etc.
You will have to provide the react element to the store in some way (probably by calling menuToggle with the actual react element).
Alternatively you could use componentDidMount to set the ref on the Body class so that toggle could consume it.
A pattern that I have used with some success is to create an initialize action that takes as one of its arguments a React component. Then in componentDidMount() you can call that action, passing this as an argument. This allows your store to have a handle on that React element, as well as all of its associated properties so you can do things like React.findDOMNode(component.refs['someref']).

Categories

Resources