How to access state of one component into another component in react - reactjs

import React, { Component } from 'react';
class one extends React.Component
{
constructor()
{
super();
this.state = {
number:26
}
}
render()
{
return(
<div></div>
);
}
}
export default one;
import React, { Component } from 'react';
import one from './one'
class HomePage extends React.Component
{
render()
{
return(
<div>{one.state.number}</div>
);
}
}
export default HomePage;
is it possible to access number state
is there any way to access state of one component into another component?
please suggest me if any solution is present.

As Shubam has explained it, Though I would like to form it as a complete answer
First of all, I would like to let you know that Never Use lowercase letters to name your React Components.So name your component to One instead of one.
Now Comming back to your question:-
No This is not Possible, If your app contains few components then it's better to pass the state object as the props, But if your app contains too many components then better to use predictable state containers like Redux or Flux rather than passing state as props.
So you may apply these changes and I hope You will get What You Desire:-
One Component:-
import React, { Component } from 'react';
import Homepage from './homepage';
class One extends React.Component
{
constructor()
{
super();
this.state = {
number:26
}
}
render()
{
return(
<Homepage data={this.state}/>
);
}
}
export default One;
Homepage Component:-
import React, { Component } from 'react';
class Homepage extends React.Component
{
render()
{
console.log("this is homepage",this.props);
return(
<div>{this.props.data.number}</div>
);
}
}
export default Homepage;
Please Raise Your doubts if any, Or if you find any error in it.

Related

Can a child component render its parent content only?

I'm extending a parent component that is part of an SDK (AWS Amplify - SignIn), which I have no control over. I only need to make a small change where the input field data will be modified to be lowercase before it's passed to the authentication function.
import React from "react";
import { SignIn } from "aws-amplify-react";
export class CustomSignIn extends SignIn {
constructor(props) {
super(props);
this._validAuthStates = ["signIn", "signedOut", "signedUp"];
}
showComponent(theme) {
return (
<div>My child component that I don't need to render</div>
);
}
}
export default CustomSignIn;
This is more of a general question not specifically related to AWS Amplify, but I'd like to use the existing UI / rendering code from the parent — is there a way to simply display the parent's rendering content and not have any child content?
You can extend a component and use that components render function.
class ComponentFromThirdParty extends React.Component {
render() {
return <div>This is ComponentFromThirdParty</div>;
}
}
class MyComponent extends ComponentFromThirdParty {
componentDidMount() {
console.log(
"MyComponent was mounted and I render the same as ComponentFromThirdParty"
);
}
render() {
return super.render();
}
}
MyComponent will render this when mounted.
This is ComponentFromThirdParty

How to use eval() to import components dynamically in react-native

I am trying to import a class component from a js file placed in external storage dynamically,
sample.js
import React, { Component } from 'react';
import { View, Text } from 'react-native';
var HeaderComponent=eval(`class HeaderComponent extends Component {
constructor(props) {
super(props);
}
render() {
return <Text>This is header</Text>;
}
}`)
class App extends Component {
constructor(props) {
super(props);
}
render() {
return <View>{HeaderComponent}</View>;
}
}
when i run the above code, I got following error,
SyntaxError: Unexpected token '<'
this error apparently indicates the following return statement(which is inside eval()),
return <Text>This is header</Text>;
May i know if this is the right way of doing dynamic import?. If not, Please let me know the right way of doing the dynamic import in react-native.
The eval() is basically a function that is used for doing Arithmetic operations, It can’t used for import a Component or any thing else,
here's a link from where you can learn about eval()
For import component you can do that with several ways
import statement:
import <Your Component Name> from '<Your Component Path>'
require()
const <Your Component Name> = require('<Your Component Path>')
you just need to add one of the above line at top of the files where you've declared other imports
use import/export keywords. add export at the end of the file, and import at the top
import React, { Component } from "react";
import { Text, View } from "react-native";
class HeaderComponent extends Component {
constructor(props) {
super(props);
}
render() {
return <Text>This is header</Text>;
}
}
class Test extends Component {
constructor(props) {
super(props);
}
render() {
return <View><HeaderComponent/></View>;
}
}
export default Test;

React class instances

I made a dummy React component that does nothing but prints out its this value.
import React from 'react'
import ReactDOM from 'react-dom'
class MyComponent extends React.Component {
constructor() {
super()
}
componentDidMount() {
console.log(this)
}
render() {
return <div />
}
}
const myComponent = new MyComponent()
console.log(myComponent)
ReactDOM.render(<MyComponent />, document.getElementById('app'))
I expected that console.log(myComponent) would produce the same result as console.log(this). However, the latter has additional properties (e.g. _reactInternalFiber) and some properties are different (e.g. context, props).
My question is, how is React or ReactDOM able to provide these additional attributes? You would think that all instances of MyComponent would have the same attributes since they have the same constructor() function, but that is not the case here.

Subclassing react components, HOC or classic OO?

I am in the process of writing a React application which is responsible for rending content from an external CMS.
Content is pulled from the CMS into a redux store when the application first loads and is accessed via connected components or props throughout its life-cycle.
I need certain methods to be available across all components making use of CMS'd content.
After researching the "React" way of achieving this, it seems the following way is generally frowned upon whilst using higher order components is viewed as a better practice. Coming from an OO background, I'm struggling to understand why?
For example...
import React, { Component } from 'react';
class CMSComponent extends Component {
constructor(props) {
super(props);
}
mySharedMethod(path) {
// Assume CMS content is located in this.props.content unless otherwise stated
// Please be aware that the actual code has been simplified massively for the sake of the question
return this.props.content[path]
}
}
I now have a base class that all my CMS components can inherit from, like so...
import CMSComponent from './components/cms'
class Page1 extends CMSComponent {
constructor(props) {
super(props);
}
render() {
// mySharedMethod() inherited from base class
return <div>{ this.mySharedMethod(['data', 'intl', 'my-keyed-content']) }</div>
}
}
If anyone could shed any light on why this is considered incorrect I would be extremely grateful.
For reference, I guess the same scenario using HOC would look something like this...
import React, { Component } from 'react'
export default function CMSInject(ChildComponent) {
class CMSComponent extends Component {
constructor(props) {
super(props);
}
mySharedMethod(path) {
return this.props.content[path]
}
render() {
return <ChildComponent {...this.props} {...this.state} /* and some refs */ />
}
}
return CMSComponent
}
...then export the child via the higher order parent component...
import React, { Component } from 'react'
class Page1 extends Component {
constructor(props) {
super(props);
}
render() {
// mySharedMethod() still inherited from base HOC class
return <div>/* CMS BASED CONENT HERE */</div>
}
}
export default CMSInject(Page1)

componentDidMount method not triggered when using inherited ES6 react class

I'm trying to use ES6 classes inside of React, and want all my components to inherit certain methods, however as soon as I try to extend a component which extends the React.Component class, the componentDidMount method doesn't trigger and hence nothing gets rendered. The code I'm using:
BaseComponent.jsx
import React from 'react';
class BaseComponent extends React.Component {
constructor() {
super();
console.log('BaseComponent constructor');
}
render() {
return (
<div>Hello, Im the base component</div>
);
}
}
export default BaseComponent;
ExampleComponent.jsx
import BaseComponent from './BaseComponent';
class ExampleComponent extends BaseComponent {
constructor(props) {
super(props);
}
componentDidMount() {
console.log('exampleComponent mounted');
}
render() {
return (
<div>Hello, Im the example component</div>
);
}
}
export default ExampleComponent;
App.jsx
import React from 'react';
React.render(<ExampleComponent />, document.body);
I'm using React 0.13.3, and using babelify 6.1.2 to transpile.
The string 'exampleComponent mounted' never gets logged to console, and nothing is rendered. Any ideas what I'm doing wrong?
I'm not sure about the approach, but this code also works:
export default class Service extends BaseComponent {
componentDidMount(...args) {
super.componentDidMount.apply(this, args);
}
}
UPD: this is considered to be a bad practice though:
a) https://medium.com/#dan_abramov/how-to-use-classes-and-sleep-at-night-9af8de78ccb4
b) https://medium.com/#dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750
I think, the problem is that you cannot create deeper class-structures for react components. Also, you shouldn't have to need it. On your example the BaseComponent is useless anyway.
Try this instead:
import React from 'react';
export default class ExampleComponent extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
console.log('exampleComponent mounted');
}
render() {
return (
<div>Hello, Im the example component</div>
);
}
}
If you want to create 'BaseComponents', you could implement them as mixins or simply as 'sub components'.
This could look like this:
import React from 'react';
import BaseComponent from './BaseComponent';
export default class ExampleComponent extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
console.log('exampleComponent mounted');
}
render() {
return (
<div>
<div>Hello, Im the example component</div>
<BaseComponent />
</div>
);
}
}
EDIT: Also possible:
import React from 'react';
import BaseComponent from './BaseComponent';
export default class ExampleComponent extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
console.log('exampleComponent mounted');
}
render() {
return (
<BaseComponent
<div>Hello, Im the example component</div>
</BaseComponent>
);
}
}
// BaseComponent.js
render() {
return {
<div>
<div>Hello, Im the base component</div>
{this.props.children}
</div>
}
}
EDIT #2: Above code works fine with es5/jsx syntax.
DEMO

Resources