Krishna Karki
Krishna Karki

Reputation: 797

React Redux setState after action is dispatched

This is my EditStudent component in React where I am using Redux for state management. This is my code of the component.

import React, { Component } from 'react'
import {connect} from 'react-redux';
import {getStudentDetail} from '../actions/studentActions';

class EditStudents extends Component {
    constructor(props){
        super(props);
        this.onInputChange = this.onInputChange.bind(this);
        this.state = {
            name:this.props.student.name,
            email:this.props.student.email,
            address:this.props.student.address
        }
        // this.state

    }

  render() {    
    return (
      <div>
      <form>
              <p>
                 <label>Name</label>
                 <input type="text" name="name" 
                 value={this.state.name} 
                 onChange={this.onInputChange}
                />
              </p>
              <p>
                 <label>Email</label>
                 <input type="text" name="email" 
                 value={this.state.email} 
                 onChange={this.onInputChange}
                 />
              </p>
              <p>
                 <label>Address</label>
                 <input type="text" name="address"
                  value={this.state.address} 
                  onChange={this.onInputChange}
                  />
              </p>
            <button type="submit">Update</button>
          </form>

      </div>
    )
  }
  onInputChange(e){
      var name = e.target.name;
    this.setState({[name]:e.target.value});

  }

  componentDidMount(){
      this.props.getStudentDetail(this.props.studentId());
  }
}

let mapDispatchToProps = (dispatch,ownProps)=>{
    return {
        getStudentDetail: (id)=>{
            dispatch(getStudentDetail(id));
        },
        studentId: ()=>{
            return ownProps.match.params.id;
        }

    }
}

const mapStateToProps = (state)=> {
    return {
        student:state.students.student
    }
}


export default connect(mapStateToProps,mapDispatchToProps)(EditStudents);

Here I am having the problem displaying ajax response in text input field. I am setting component in the constructor but when ajax request completes state is not set.

Is it possible to set state after ajax completes?

Upvotes: 3

Views: 9073

Answers (3)

Ankit Kumar Rajpoot
Ankit Kumar Rajpoot

Reputation: 5590

There are two ways

First -

  constructor(props) {
    super(props);
    this.state = {
      firstName: ""
    };
  }

  componentDidMount() {
    this.props.userProfile();     // Redux Action
  }

  componentWillReceiveProps(nextProps) {
    console.log(nextProps);
    this.setState({
      firstName: nextProps.user.firstName
    });
  }

Second -

  constructor(props) {
    super(props);
    this.props.userProfile();   // Redux Action
    this.state = {
      firstName: ""
    };
  }

  static getDerivedStateFromProps(props, state) {
    return {firstName: this.props.user.firstName };
  }

Upvotes: 0

Krishna Karki
Krishna Karki

Reputation: 797

I solve it by adding componentWillReceiveProps() function on component.

componentWillReceiveProps(nextProps){
    this.setState({
        name:nextProps.student.name,
        email:nextProps.student.email,
        address:nextProps.student.address
    })
  }

Thanks so much, Sakhi Mansoor for the help.

Upvotes: 6

Sakhi Mansoor
Sakhi Mansoor

Reputation: 8102

you need to store input value in your state as you're re-rendering your input so changes are not getting reflected.

Do the folowing changes:

constructor(props){
    super(props);
    this.onInputChange = this.onInputChange.bind(this);
    this.state = {
        email:this.props.student.email,
        address: this.props.student.address
    }
}

In you render:

<p>
   <label>Email</label>
   <input type="text" name="email" value={this.state.email} onChange={this.onInputChange('name)}/>
</p>
<p>
   <label>Address</label>
   <input type="text" name="address" value={this.state.address} onChange={this.onInputChange('name')}/>
</p>


onInputChange= name => event => {
        this.setState({
          [name]: event.target.value,
         });
   };

Upvotes: 1

Related Questions