// parent class
export default class HomeScreen extends React.Component {
constructor(props){
super(props);
this.state = {
password: '',
username:'',
session: 'mani',
};
}
authentication(){
const self = this;
axios.post('/api/users/login/', {
password: this.state.password,
username: this.state.username
})
.then(function (response) {
console.log(response);
var sessionid=response.headers["set-cookie"][0].split('Secure,').pop().split(';').shift();
self.setState({session: sessionid });
})
.catch(function (error) {
console.log("Invalid username/password");
});
}
render(){
return(<Session sessid={this.state.session}/>);
}
}
export default class Session extends Component {
constructor(props){
super(props);
this.sessionVariable = this.props.sessid;
}
render(){
console.log(this.props.sessid); // here i am getting updated value
console.log("constructor "+this.sessionVariable); // here i can't able to get updated value
return (<View></View>);
}
}
//child class
import React, { Component } from 'react'
import { View, Text } from 'react-native'
export default class Session extends Component {
constructor(props){
super(props);
this.state = {
sessid: this.props.sessid
}
}
componentWillReceiveProps(nextProps){
const { sessid } = nextProps;
if (sessid !== this.state.sessid) {
this.setState({sessid});
}
}
render(){
console.log(this.props.sessid);
console.log("dummy"+this.state.sessid);
return (<View></View>);
}
}
How to get updated data into constructor in React
Can you please give me the quick solution
I need to update the data in constructor . Then only I am able to call the global variable throughout the all components
How to get updated data into constructor in React
Can you please give me the quick solution
I need to update the data in constructor . Then only I am able to call the global variable throughout the all components
Add your props value inside the state and update it using componentWillReceiveProps ' lifecycle.
constructor(props) {
super(props);
this.state = {
sessid: this.props.sessid;
};
}
componentWillReceiveProps(nextProps){
const { sessid } = nextProps;
if(sessid !== this.state.sessid) {
this.setState({sessid});
}
}
You can use states to check that current condition, let me explain it with an example,
This is the constructor with initial state for the data toggle
constructor(props){
super(props);
this.state = {
toggle: true;
}
}
Update the existing state, do this
this.setState({ toggle: false });
Make sure you are using the above code inside an arrow function or else bind the .this
If you want more info comment that below...
The only reason that it doesn't show the updated value is because constructor is called only on the initial mount of the component and hence whatever class variable is set in constructor based on props, it won't be updated if the props change.
Second: setting a state or a class variable which is directly derivable from props is an anti pattern and you should just use props directly in render
export default class Session extends Component {
render(){
console.log(this.props.sessid);
return (
<View>
</View>
)
}
}
Still if you want to update the class variable based on, you can make use of componentWillReceiveProps function like
componentWillReceiveProps(nextProps) {
if(nextProps.sessid !== this.props.sessid) {
this.sessionVariable = nextProps.sessid;
this.forceUpdate(); // called to cause a re-render
}
}
or
export default class Session extends Component {
constructor(props) {
super(props);
this.state = {
sessionVariable: props.sessid
}
}
componentWillReceiveProps(nextProps) {
if(nextProps.sessid !== this.props.sessid) {
this.setState({ sessionVariable: nextProps.sessid});
}
}
render(){
console.log(this.state.sessionVariable);
return (
<View>
</View>
)
}
}
In your constructor define a state:
constructor(props) {
super(props);
this.state = {
sessionVariable: props.sessid;
};
}
Now, in your render():
console.log(props.sessid);
console.log("constructor "+ this.state.sessionVariable);
The constructor for a React component is called only before it is mounted. If you define some variable in constructor, it will store its value not reference and will not be re render again.
To change any value defined in constructor, you need to change it in updating phase of react (ComponentWillReceiveProps) and then call the
this.forceUpdate(); // to render the component
eg.
componentWillReceiveProps(nextProps) {
if(this.props.sessid !== nextProps.sessid) {
this.sessionVariable= nextProps.sessid;
this.forceUpdate();
}
}
Or you can directly use props in render function.
Related
I'm new to React working on an existing React component (that appears to be built in an older style - no hooks).
I want to read and set state within a handler function. I have the following code:
export default class MyComponent extends React.Component {
static defaultProps = {
data: {}
};
constructor(props) {
super(props);
// Other states
this.state.myState = false;
};
handleMyChange() {
if (!this.state.myState) {
console.log("hello world");
}
}
However I get the error Cannot read properties of undefined.
I've tried various like state.myState but am not really sure what I should be doing.
Can anyone point me in the right direction?
In order to have this context in your function, you will need to bind it in the constructor first
Here is a small example is taken from the official doc:
import React from "react";
export default class SayHello extends React.Component {
constructor(props) {
super(props);
this.state = { message: "Hello!" };
// This line is important!
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
alert(this.state.message);
}
render() {
// Because `this.handleClick` is bound, we can use it as an event handler.
return <button onClick={this.handleClick}>Say hello</button>;
}
}
When I change my state, I can read newData in Main Component but my update state doesn't go my ChildComponent. I read only initialData in my ChildComponent. Why doesn't go my new props to ChildComponent? or Why doesn't reRender my ChildComponent ?
class Main extends Component{
constructor(props) {
super(props);
this.state = {
data: "initalData",
}
}
componentDidMount(){
this.changeState();
}
changeState(){
this.setState({data: "newData"})
}
render(){
console.log("my data in Main :",this.state.data)
return(
<ChildComponent dataProps={this.state.data}>
)
}
class ChildComponent extends Component{
constructor(props) {
super(props);
const getData = props.dataProps;
console.log("getData is ",getData)
this.state = {
...,
}
}
}
It's because the constructor of the class component only run once when you initialize it but not every render.
To always get the latest value, you would need to put them inside the class component body below the constructor.
Something like this:
class ChildComponent extends Component{
constructor(props) {
super(props);
this.state = {
...
}
}
const getData = this.props.dataProps;
console.log("getData is ", getData)
render() (
...
)
}
You can use the below to update each time props that get passed to it changes
componentDidUpdate(prevProps, prevState, snapshot){
if(prevProps !== this.props){
this
}
}
ComponentDidUpdate docs
Current Code
Parent.js
export default class Parent extends Component {
constructor(props) {
super(props);
this.state = {
nickname: 'parent'
};
}
}
Child.js
export default class Child extends React.Component {
constructor(props) {
super(props);
this.state = {
nickname: props.navigation.state.params.nickname
};
}
onPressUpdate() {
const { nickname } = 'Child';
this.props.navigation.navigate('Parent', { nickname: nickname });
}
}
What I'm Trying To Do
Parent.js displays nickname and it is edited in Child.js.
Finishing to edit nickname, navigation goes back to Parent.js.
Then I wanna display a new nickname, 'Child' in above code.
I would appreciate it if you could give me any advices :)
You could use componentDidUpdate in parent code.
Something like this:
componentDidUpdate(prevProps) {
// Typical usage (don't forget to compare props):
if (this.props.nickname !== prevProps.nickname ) {
this.seteState({nickname:this.props.nickname});
}
}
When you navigate from child to parent, pass the nickname to update, it will work and setState to new one.
I have a react component I'm creating as a local variable. I'd like to tweak its state before attaching it to the DOM. A super-simplified version of the code looks like this:
class Demo extends React.Component {
constructor(props) {
super(props);
this.state = {foo: 2};
}
render() {
return <p>{this.state.foo}</p>;
}
}
class App extends React.Component {
render() {
let elem = <Demo/>;
elem.setState({foo:4});
}
}
(The real code has a point, but I'm posting the simplified test case so you don't have to read long irrelevancies)
I'm getting the error
TypeError: elem.setState is not a function
What does this error mean? I'm checked that element is an instance of Demo.
Is there a way to set the state at this time?
ETA: I know what props is. I really want to modify the element after creating it.
You can't setstate like this. If you want to manipulate state in the child component you have to add props to do that.
import React, { Component } from "react";
class Demo extends Component {
state = {
foo: this.props.foo || 0
};
componentDidUpdate(prevState) {
console.log(prevState.foo, this.props.foo);
if (prevState.foo !== this.props.foo) {
this.setState({ foo: this.props.foo });
}
}
render() {
return <button {...this.props}>{this.state.foo}</button>;
}
}
export default class App extends Component {
state = {
count: 0
};
clickMe = () => {
this.setState({
count: this.state.count + 1
});
};
render() {
return <Demo onClick={() => this.clickMe()} foo={this.state.count} />;
}
}
Here is working example https://codesandbox.io/s/festive-rhodes-redk7
I have a state inside of child component that I want to use in parent component. This is how my components set:
Child:
export default class Child extends React.PureComponent {
constructor() {
this.state = {
value: "123",
};
}
updateValue(data){
this.props.updateValue(data);
}
componentWillMount(){
this.updateValue(this.state.value);
}
}
Parent:
export default class Parent extends Component {
constructor() {
super(props)
this.state = {
newValue: ""
};
}
updateState (data) {
this.setState(newValue: data);
}
render() {
return(
<Child updateValue={this.updateState.bind(this)}/>
)
}
}
However, it doesn't seem to work and gives me an error. Am I doing something wrong?
Remember that this.setState takes an argument. You have passed a key:value pair that isn't stored in a data structure.
this.setState(newValue: data);
should be
this.setState({newValue: data});