Can I set state of imported component in react native? - reactjs

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>
)
}}

Related

Props are empty on passing them to child class based components while filled when using functional component

It seems that props are not being passed to child component when my child component is a class based component. This is my parent component:
class ScreeningsList extends React.Component{
state = {screenings: [] };
componentDidMount = async () => {
const response = await apis.getAllScreenings();
this.setState({screenings: response.data});
}
render(){
return (
<div>
<ScrTest screeningsList = {this.state.screenings}/>
</div>
)
}
}
And here is my child component:
class ScrTest extends React.Component{
render(){
return (
<div className="screeningsContainer">
<h2>Title: {this.props.screeningsList._id}</h2>
</div>
)
}
}
Here I tried just to display id of the screening. The value in props did not exist. There were no props at all.
However when I use functional component and use the arrow function:
const ScreeningsToRender = props => {
...
}
I can access props by using props.screeningsList and use every value that is inside that prop. Rendering the component is succesfull and I can see the list of all the screenings. What should I do to recieve props properly in my child component?
You need a constructor in the child component:
class ScrTest extends React.Component{
constructor(props){
super(props);
}
render(){
return (
<div className="screeningsContainer">
<h2>Title: {this.props.screeningsList._id}</h2>
</div>
)
}
}
"When implementing the constructor for a React.Component subclass, you should call super(props) before any other statement. Otherwise, this.props will be undefined in the constructor".
Source: https://reactjs.org/docs/react-component.html#constructor

How to get state of class from another file React-Native

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);
}

Update parent component State from child component in react js

I am setting a state into child component on event perform and want to sent this to Parent component. I searched for this on SO. But still didn't found any way to do this.
Let say i have a parent component Home, and have child component User. I am performing some event in User component, and at that time, i want to pass data to Home component. How can i do this?
Below is my code:
/* Parent component */
import React, { Component } from 'react';
import User from './user';
class Home extends React.Component{
constructor(props){
super(props)
this.state = {
isReportSent: false
}
}
render(){
<Switch>
<Route exact path="/" component={User}/>
</Switch>
}
}
/* child component */
class User extends React.Component{
constructor(props){
super(props)
}
render(){
}
}
Note: My parent component is Routing component, in which i am routing my child component on particular path. So can't pass any function to child component.
import React, { Component } from "react";
class Home extends Component {
constructor(props) {
super(props);
this.state = {};
}
onChildAPICall = result => {
console.log(result);
};
render() {
return <User onAPICall={this.onChildAPICall} />;
}
}
class User extends Component {
constructor(props) {
super(props);
this.state = {};
this.API = "https://apicall";
}
makeAnAPICall = async () => {
let result = await fetch(this.API);
this.props.onAPICall(result);
};
render() {
return <button onClick={this.makeAnAPICall}>API Call</button>;
}
}
export default Home;
Something like this would work. I'm not sure if the below is 100% functioning as I just wrote it quickly but the idea is to pass down setState() as a prop from parent to child. So when child calls setState from props it's setting state in the parent component.
class Home extends React.Component {
constructor (props) {
super(props)
this.state = {
data: []
}
}
render () {
<ChilComponent setState={this.setState} />
}
}
const User = async ({ setState }) => {
const receivedData = await getDataHowever(params)
setState({
data: receivedData
})
return (
<p>Got data!</p>
)
}
You can call callback function of parent from child component and in parent you can set the state based on callback response.
import React, { Component } from "react";
class Home extends Component {
constructor(props) {
super(props);
this.state = { }
}
setStateOfParent= result => {
this.setState({result : result});
}
render() {
return <User setStateOfParent={this.setStateOfParent} />;
}
}
class User extends Component {
constructor(props) {
super(props);
this.state = {};
this.API = "https://apicall";
}
makeAnAPICall = async () => {
let result = await fetch(this.API);
this.props.setStateOfParent(result);
};
render() {
return <button onClick={this.makeAnAPICall}>API Call</button>;
}
}
export default Home;
Your explanation is not all clear what you want to acheive but as a simple pattern you can pass the callback prop to the child component using render method of react router
Parent Component
<Route exact path="/" render={(props) => <User {...props} callback={this.callback} />}/>
Child Class
this.props.callback(data)
#user10742206 The best way is to create an independent component and include it as a child in any parent component. Then you can pass a callback function from parent and child can use it to send back any data to parent.

Pass State from component to parent

If have a Listing page that contains a table component:
class ListingPage extends Component {
static propTypes = {
getTableData: PropTypes.func.isRequired,
};
componentDidMount() {
this.props.getTableData(*I want to Pass in sortlist state here*);
}
render() {
return (
<div>
<Table />
</div>
}
And the Table component maintains a sortlist state:
class Table extends Component {
constructor(props) {
super(props);
this.state = {
sortlist: 'someStringData',
};
render() {
<div>
Table Information etc.
</div>
}
The sortlist is changed in the table component through various functions. How can I pass that sortlist state up to the ListingPage component?
Pass a function along to Table from ListingPage that gets called whenever the sortlist is changed.
ListingPage component:
class ListingPage extends Component {
static propTypes = {
getTableData: PropTypes.func.isRequired,
};
onSortChange(s) {
console.log(s);
}
render() {
return (
<div>
<Table onSortChange={s => this.onSortChange(s)} />
</div>
);
}
}
Table component:
class Table extends Component {
constructor(props) {
super(props);
this.state = {
sortlist: 'someStringData',
};
}
somethingThatTriggersSortListToChange(s) {
this.props.onSortChange(s);
}
render() {
return <div>Table Information etc.</div>;
}
}
Considering above answer, You can also use redux store in this case when you want to pass state from child to parent. Make an action call and store the state in redux store and get the state in parent component. This is another way of playing from child to parent component.
this.props.saveToStore(this.state.sortlist);
In your action file
cost SAVE_TO_STORE = “SAVE_TO_STORE”;
export function saveToStore(sortlist){
return {
type: SAVE_TO_STORE,
sortlist
}
}
Like store state in reducer and get the state in your parent component and return as props i.e., in mapStateToProps(state, props) function using redux connect method.

Check state from imported component

Much of a basic question. Can I pass the state property to another component? So if I create a login app and after a successful login from API call I set the state of loggedInUser: 12345 in say a component called Login.js
export default class Login extends Component {
constructor(props) {
super(props);
this.state = {
data:[],
loggedInUser: 12345
}
}
render(){
return(
//Return the this.state.loggedInUser
)
}
}
How can I pass this.state.loggedInUser from Login.js to another component where I've imported Login.js?
For example, in my Page1.js I have import Login from './Login'
Can something like this be achieved? I just want to pass the this.state.loggedInUser value to any page where it us imported.
Thanks.
As mentioned in the comment above, redux is probably best practice here. But here is an example of accomplishing this with vanilla react.
export default class Parent extends Component {
constructor(props) {
super(props)
this.state = {
logginUser: undefined
}
this.handleUserState = this.handleUserState.bind(this);
}
handleUserState = (userInfo) => {
this.setState({logginUser: userInfo})
}
render = () => {
return (
<div>
<Login handleUserState={this.handleUserState} />
</div>
)
}
}
export default class Login extends Component {
constructor(props) {
super(props);
this.loginUser = this.loginUser.bind(this);
}
loginUser = (e) => {
e.preventDefault()
<--- make call to api for userInfo here and pass it to the call below --->
this.props.handleUserState(userInfo)
}
render =() => {
return(
<div>
<button type="submit" onClick={this.loginUser} />
</div>
)
}
}
Basically what's happening here since you are importing Login into another component, you will have that 'Parent' component act as the state manager and save the user data at that level. You then pass the function that updates the state to the Login component and call it once you have the user data to update it with.
I hope this helps!

Resources