Piyush
Piyush

Reputation: 1193

Not getting desired values in input fields React redux or ReactJS

enter image description hereenter image description here

import React, { Component } from 'react';
let _ = require('lodash');

import {bindActionCreators} from "redux";
import {connect} from 'react-redux';

import {fetchedZonesEdit} from '../../actions/';

class InfoRow extends Component {

  constructor(props){
    super(props); 
    this.handleInputChange = this.handleInputChange.bind(this);
  }

  handleInputChange(event) {

        this.setState({
            [event.target.name]: event.target.value
        });

    }

    render() {
        return (
            
            <tr>
                <td>
                  {this.props.zone}
                </td>
                <td>{this.props.zoneValue}
                <input type="text"
                   className="form-control"
                   defaultValue={this.props.zoneValue}
                   value={this.props.name}
                   name={this.props.zone}
                   onChange={this.handleInputChange}
                />
                </td>
            </tr>
        )
    }
}

class ZoneDetailsEdit extends Component {

    render() {

        const rows = [];
        let a = this.props.ezn;
        

       Object.keys(this.props.ezn).map((keyName, keyIndex) =>{

          return rows.push(<InfoRow zone={keyName} zoneValue={a[keyName].toString()} key={keyIndex}/>)
       });

        return (


            <div className="col-md-6">
                <div className="">

                  <table className="table table-clear">
                    <tbody>
                      {rows}
                    </tbody>
                  </table>
                 </div>
                 <div className="row px-1" >
                      <div className="px-2">
                        <button className="btn btn-sm btn-info">Save</button>
                 </div></div>
          </div>

        )

    }


}

class ZoneDetailEditComponent extends Component {

  componentWillMount = () => {
        this.props.fetchedZonesEdit(this.props.location.query.id);
    };

  
  render() {
    
    return (
        <div className="container px-3 mr-3">
            <div className="row">
              <div className="col-md-6 col-md-offset-3"><h1>Edit Tag Information</h1></div>
            </div>
            <br/>
            <br/>
                { this.props.ezn != null?
            <div>
                <ZoneDetailsEdit ezn={this.props.ezn}/>
            </div> :
                    <center><br /><h1><img src={'img/avatars/default.gif'} alt="Loading"/><br />Loading</h1></center>

            }
        </div>
    )
  }
}

function mapStateToProps(state) {
    return {
        ezn: state.zones
    }

}


function matchDispatchToProps(dispatch){
    return bindActionCreators({fetchedZonesEdit: fetchedZonesEdit}, dispatch);
}

export default connect(mapStateToProps, matchDispatchToProps)(ZoneDetailEditComponent);

This is the snippet i provided what I'm doing right now is i had fetched the data from the api and was shown in the input fields but the issue is data is fetched correctly but when i print outside input fields it works fine but when i enter in input fields as default value it doesn't works screenshot also provided when opened the page default values are set of previous page but when it is refreshed it works fine

Upvotes: 0

Views: 158

Answers (2)

Shubham Khatri
Shubham Khatri

Reputation: 281616

Since you are using a controlled component you need not use defaultValue, assigning the props passed down to the value will suffice.

Also using redux, a better practice is to store the UI state in localState and all others in the redux store.

To do that you need to dispatch an action that updates the corresponsing reducer after passing the values to the topmost parent

Also you are not passing any prop as name to the InfoRow component and since defaultValue is rendered only at the time of create, you do not see the update.

You code must look something like

import React, { Component } from 'react';
let _ = require('lodash');

import {bindActionCreators} from "redux";
import {connect} from 'react-redux';

import {fetchedZonesEdit} from '../../actions/';

class InfoRow extends Component {

  constructor(props){
    super(props); 
    this.handleInputChange = this.handleInputChange.bind(this);
  }

  handleInputChange(event) {

        this.props.handleChange(this.props.zone, event.target.value);


    }

    render() {
        return (

            <tr>
                <td>
                  {this.props.zone}
                </td>
                <td>{this.props.zoneValue}
                <input type="text"
                   className="form-control"
                   value={this.props.zoneValue}
                   name={this.props.zone}
                   onChange={this.handleInputChange}
                />
                </td>
            </tr>
        )
    }
}

class ZoneDetailsEdit extends Component {

    handleChange(zone, value) {
         //pass it to the parent and then fire an action from there to update this value in the store

    }
    render() {

        const rows = [];
        let a = this.props.ezn;


       Object.keys(this.props.ezn).map((keyName, keyIndex) =>{

          return rows.push(<InfoRow zone={keyName} zoneValue={a[keyName].toString()} handleChange={()=> this.handleChange}key={keyIndex}/>)
       });

        return (


            <div className="col-md-6">
                <div className="">

                  <table className="table table-clear">
                    <tbody>
                      {rows}
                    </tbody>
                  </table>
                 </div>
                 <div className="row px-1" >
                      <div className="px-2">
                        <button className="btn btn-sm btn-info">Save</button>
                 </div></div>
          </div>

        )

    }


}

Also there is no need for you to bind the lifeCycle function with arrows

Upvotes: 1

Sulthan
Sulthan

Reputation: 130072

defaultValue should be used only on Uncontrolled components.

Instead of using defaultValue, assign a default value to the name in your store.

Also, don't use this.setState if you are using redux. You are assigning the new value to this.state.zone which you never read.

Upvotes: 2

Related Questions