0
votes

I have been experimenting couple of days with ReactJS and ES6 and created couple of components i.e. <InputText />, <InputNumber />, <InputEmail />, that are being used in the component <ContactsEdit />.

It seems really strange that even though I have read many tutorials my child components refuse to render() the {this.state.Firstname} even though I tried componentWillMount, componentDidMount, this.setState, this.state with this.forceUpdate(), but they will render fine the this.props.Firstname

I would welcome any kind of suggestions or help. The source can be found at github

Thanks :)

` export default class ContactsEdit extends React.Component {

constructor(props) {
    super(props);

    this.contactId = this.props.params.id;
    this.persistence = new Persistence('mock');

    this.state = {
        contact : {}
    };

}

componentDidMount() {
    this.persistence.getContactById( this.contactId ).then( (resolve) => {
        this.setState({ contact : resolve.data });
        this.data = resolve.data;
    }).catch( (reject) => {
        console.log(reject);
    }) ;

    this.forceUpdate();
}

onChange(id,newValue)  {
    this.state.contact[ id ] = newValue;
    this.forceUpdate();
}

saveRecord( object ) {
    console.log( this.state );
}

render() {
    return (            
        <div className="ContactsEdit">
            <h2>Contact Edit (Parent) id : {this.props.params.id}, FullName : {this.state.contact.Firstname} {this.state.contact.Lastname}</h2>
            <div className="row">                    
                <InputText id="Firstname" fieldName={this.state.contact.Firstname}  labelName="Firstname" onChange={this.onChange.bind(this)} divClass="col-lg-3 col-md-3 col-sm-3 col-xs-6" />
                <InputText id="Lastname"  fieldName={this.state.contact.Lastname}  labelName="Lastname"  onChange={this.onChange.bind(this)} divClass="col-lg-3 col-md-3 col-sm-3 col-xs-6" />
                <InputText id="SocSecId"  fieldName={this.state.contact.SocSecId}  labelName="SocSecId"  onChange={this.onChange.bind(this)} divClass="col-lg-3 col-md-3 col-sm-3 col-xs-6" />
                <InputText id="DriverLicId"  fieldName={this.state.contact.DriverLicId}  labelName="DriverLicId"  onChange={this.onChange.bind(this)} divClass="col-lg-3 col-md-3 col-sm-3 col-xs-6" />
            </div>

        </div>
    )
}

}

`

` export default class InputText extends React.Component {

constructor(props) {
    super(props);         
    this.state = { fieldName : this.props.fieldname}; 
}

componentWillMount() {
    //this.state.fieldName = this.props.fieldname;
    //this.forceUpdate();
}

updateState(evt) {
    //this.setState( {fieldName : evt.target.value} );
    this.props.onChange( evt.target.id, evt.target.value     );
}

render() {
    return (
        <div className={this.props.divClass}>
            <hr />
            <label> {this.props.labelName} </label>
            <div>{this.props.fieldName}</div> 
            <div>{this.state.fieldName}</div> 
            <input 
                type="text" 
                id={this.props.id} 
                value={this.props.fieldName} 
                onChange={this.updateState.bind(this)} 
                className="form-control"
            />
        </div>
    )
}

} `

2
Welcome to Stack! Just post the relevant code here in your question, which will (hopefully) remove the downvotes and get you the answers you need. - azium
Thanks :) I will do that :) - Sotiris Karanasios

2 Answers

1
votes

this.props doesn't exist in the constructor function until after its run, binding this to an instance of the class. Use the props that are passed in from the parent (in the argument)

constructor (props) {
    super(props)
    this.state = { fieldName: props.fieldname }
}

componentWillMount is replaced by using ES6 class constructor

Also you should not modify this.state directly. It won't cause react to call render(). Only set the initial state in constructor. Everywhere else, call this.setState({ data: newData }).

0
votes

The reason I am posting the topic and the GitHub link is that I have tried everything. I know that using this.state is not best practice and I have used it in conjuction with this.forceUpdate because the this.setState() would not work.

I am also aware that componentWillUpdate() has been replaced in ES6 but removing it and only using the constructor() wouldn’t do the job for me.

I have also tried

constructor(props) {
    super(props);
    this.setState({ fieldName : 'something' })
// …

but that only led to hardcoding the value into my component. I have tried returning the value using a promise:

constructor(props) {
    super(props);

    MyPromise( (resolve) => {
       this.setState({ fieldName : resolve})
    }
// …

but that did not work either.

So I started wondering if maybe there is something wrong with my gulpfile (thus providing the GitHub repo so someone with more expertise could maybe check and help).

Very strangely, though, the this.props solution worked even though I understand it’s not the best practice.