I am trying to get state of a class from another class but it throws an error "cannot read property 'state' od undefined". My approach is when the user press the button the "FromStr" state get redirect to another class B from A. i tried
import React, { Component } from "react";
import { StyleSheet, Text, View, TextInput, Button } from "react-native";
import styles from "./appstyles";
import {getValue} from "./main"
export default class A extends Component{
constructor (props) {
super(props)
this.state={
From:'',
FromStr:'',
}
}
changeText=(From)=>{
this.setState({From})
}
onPress = ()=>{
this.setState({FromStr: this.state.From})
this.fetch()
}
fetch(){
getValue();
}
render(){
return (
<View>
<View style={styles.inputFields}>
<TextInput placeholder="From" id="from" style={styles.fromField} onChangeText={this.changeText} />
<View style={styles.buttonStyle}>
<Button
title={"Go Back"}
color="#f194ff"
onPress={this.onPress}
></Button>
);
}
}
Class B
import React, { Component } from "react";
export function getValue(){
alert(this.state.FromStr);
}
Shared state between components by direct access is an anti-pattern. Each component should have its own state. If you need globally, please consider using Redux.
Passing state as props is also valid, but it only works when components are in parent-child order. Redux allows components to be updated irrelevant of their relationship
As mentioned , pass state as props to their children.
class classname2 extends React.Component {
this.state = { statename1: "lala" };
render() {
return <classname1 statename1={this.state.statename1} />
}
};
class classname1 extends React.Component {
render() {
return (
<div>{this.props.statename1}</div>
);
}
};
You can define class A's this as global inside it's container. Then, call it from class B. For example;
//class A constructor
constructor(props){
super(props);
global.__classAThis = this;
}
//class B constructor
constructor(props){
super(props);
console.log(__classAThis);
//also you can update class A this
__classAthis.setState({test: true})
}
There are many ways to do this. The simplest way is to use LocalStorage .
Usage
A screen
this.setState({FromStr: this.state.From
}, () => localStorage.setItem('FromStr', this.state.From));
B screen
componentDidmount(){
const data = localStorage.getItem('FromStr')
alert(data);
}
Related
I want to set state of imported component. Something like
import ProductListing from '../components/ProductListing';
constructor(props){
super(props);
ProductListing = new ProductListing();
ProductListing.state = {someVariable : 'hello'};
}
Send data as props from the component where you want to use and inside the state of that component use it.
Example:
import UserInfo from './userInfo.js'
class UserDetail extends React.Component {
render()
{
return(
<UserInfo myNewState= {//define your state here} />
)
}
}
And inside UserInfo use this:
....
state= {this.props.myNewState}
If your aim is just to update the state of the child component in your case it is ProductListing. So you can do these steps
Create ProductListing as a react class so that you can create a reference for that
class ProductListing extends Component (){
state = {
items: []
}
updateStateItems = (data) => {
this.setState({ items: data })
}
render() {
return(
// your render method code code
)
}}
import ProductListing in your parent class and create a reference for that and in componentDidMount using the reference call functionupdateStateItems with data that you want to set in ProductListing state.
import ProductListing from './ProductListing'
class ParentClass extends Component (){
constructor(props){
super(props)
}
componentDidMount(){
// here use that reference to pass the data that you want to set in state
this.ref.updateStateItems(data)}
render() {
return(
<div>
<ProductListing
// to create a reference of product listing
ref={(ref) => { this.ref = ref }}
/>
</div>
)
}}
I am trying to triger child method by another child.
by using their parent component.
i know when working with redux i need to change fields on the store
and the the components is rerendering by the needed props.
but in this case i dont need to save any thing, just to run the first child method each press.
import React from 'react';
import Child1Container from "./Child1Container";
import Child2Container from "./Child1Container";
export default class Parentextends React.Component {
constructor(props){
super(props);
}
RunChild1Method(){
// Run Child1 Method
}
render() {
return (
<div>
<Child1Container />
<Child2Container RunChild1Method={this.RunChild1Method} />
<div>
)
}
}
Chiled2 Container
import { connect } from 'react-redux';
import Child2Component from "./Child2Component";
const mapStateToProps = (state, ownProps) => {
return {
RunChild1Method: ownProps.RunChild1Method
};
};
const Child2Container = connect(mapStateToProps)(Child2Component);
export default Child2Container ;
Child2 Component
import React from 'react';
export default class Child2Component extends React.Component {
constructor(props){
super(props);
}
render() {
return (
<button onclick={() => {this.props.RunChild1Method()}}> Click Me!</ button>
)
}
}
to achieve this use refs: https://reactjs.org/docs/refs-and-the-dom.html
export default class Parent extends React.Component {
RunChild1Method(){
if (!this.child1Ref) return;
this.child1Ref.runMethod();
}
render() {
return (
<div>
<Child1Container ref={(comp) => { this.child1Ref = comp; }} />
<Child2Container RunChild1Method={this.RunChild1Method} />
<div>
)
}
}
However (My opinion) I would strongly recommend not structuring your apps like this. Components should be an encapsulation of functionality and this is an anti-pattern which will cause future headaches.
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.
I'm working on a React Native project and I realized that React Native seems to break the React flow (Parent to children) props update.
Basically, I'm calling a "Menu" component from an "App" component, passing a prop to "Menu". However, when I update the "App" state, the props on "Menu" should update, but this doesn't happen. Am I doing something wrong?
That's my code:
App.js
import React from 'react';
import {
View,
Text
} from 'react-native';
import Menu from './Menu';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
opacity: 2
}
}
componentDidMount() {
setTimeout(() => {
this.setState({
opacity: 4
});
}, 3000);
}
render() {
return(
<View>
<Menu propOpacity={this.state.opacity} />
</View>
);
}
}
export default App;
Menu.js
import React from 'react';
import {
View,
Text
} from 'react-native';
class Menu extends React.Component {
constructor(props) {
super(props);
this.state = {
menuOpacity: props.propOpacity
}
}
render() {
return(
<View>
<Text>Menu opacity: {this.state.menuOpacity}</Text>
</View>
);
}
}
Menu.propTypes = {
propOpacity: React.PropTypes.number
}
Menu.defaultProps = {
propOpacity: 1
}
export default Menu;
React is not breaking data flow... You are. After initial state initialisation, you forget to update Menu's state later, when parent sends updated props.
Try this...
class Menu extends React.Component {
constructor(props) {
super(props);
this.state = {
menuOpacity: props.propOpacity
}
}
componentWillUpdate(nextProps, nextState) {
nextState.menuOpacity = nextProps.propOpacity;
}
render() {
return(
<View>
<Text>Menu opacity: {this.state.menuOpacity}</Text>
</View>
);
}
}
I'm writing a library full of ReactJS components, so Flux should not be used, since it's a library.
I have a component, a ThemeProvider.
import React from 'react';
class OfficeUIThemeProvider extends React.Component {
constructor(props) {
super(props);
}
render() {
return null;
}
}
OfficeUIThemeProvider.propTypes = {
theme: React.PropTypes.oneOf(['Office2016']).isRequired,
color: React.PropTypes.oneOf(['Light-Blue', 'Blue', 'Green', 'Orange', 'Purple', 'Red']).isRequired
};
export default OfficeUIThemeProvider;
I return null in the render() method since this component should not render anything.
Then I do have a simple component, a button.
import React from 'react';
class OfficeUIButton extends React.Component {
constructor(props) {
super(props);
}
render() {
return <div className={"officeui-button"}>
<span className="{officeui-button-label}">{this.props.label}</span>
</div>
}
}
OfficeUIButton.propTypes = {
label: React.PropTypes.string.isRequired,
};
export default OfficeUIButton;
Now, I want the button to have specific classes, based on the values provided in the ThemeProvider.
A simple solution would be to render the OfficeUIButton component directly in my ThemeProvider render() method but this is not a valid solution since I'm developing a library and don't want to couple things.
An application using this library should work as:
ReactDOM.render(
<OfficeUIThemeProvider theme='Office2016' color='Light-Blue'>
<OfficeUIButton label="To..." />
</OfficeUIThemeProvider>,
document.getElementById('app')
);
But, this renders nothing since my ThemeProvider return nullâ—‹ in it'srender` method.
How can this be accomplished?
Kind regards,
OfficeUIButton is child component of OfficeUIThemeProvider, so I suppose you should try:
class OfficeUIThemeProvider extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
{this.props.children}
</div>
);
}
}