3

Testing some things in React js and having some issues with some of my logic. I am trying to get value from inputs in a form then on submitting that form i want to take that object of input values and add them to my ctcList array. I am trying to use the es6 features of spread for concating my current newCtc state with my ctcList state. When i console log i get the newCtc values but then the ctcList array is empty. Any help is appreciated.

Thank you!

import React, { Component } from 'react';
import Contact from './Contact';
import TestData from './TestData';


class ContactList extends Component {
  constructor(props){
    super(props);
    this.state = {
      name: '',
      test1:'',
      test2:'',
      newCtc:{},
      ctcList:[],
      arr: []
    }
  }

  async componentDidMount() {
    try{
      const result = await fetch('https://jsonplaceholder.typicode.com/users')
      const data = await result.json()
      this.setState({arr:data})

    }catch(err){
      console.log(err)
    }
  }


  onChangeInput = (e)=>{
    const target = e.target;
    const name = target.name;
    const value = target.value;
    console.log(value)
    this.setState({
      [name]: value
    });
  }

  newSubmit = (e) =>{
    e.preventDefault();



    this.setState(Object.assign(this.state.newCtc,{test1:this.state.test1, test2:this.state.test2}));


    console.log(this.state.newCtc)

    this.addContact();



    this.clearInput();
    console.log(this.state.newCtc);

    }



    addContact = ()=>{
      this.setState({ ctcList:[ ...this.state.ctcList, this.state.newCtc] });
      console.log(this.state.ctcList);
    };




    clearInput = ()=>{
      this.setState({test1:'',test2:''});
      this.setState(Object.assign(this.state.newCtc,{test1:'', test2:''}));
    };

  render() {


    return (
      <div>
      <Contact firstName = {this.state.name} lastName='mcdaniel' phoneNumber = '585-721-3824' />
      <input type = 'text' name = 'name' onChange = {this.onChangeInput}></input>

      <TestData data={this.state.arr} />  


      <form onSubmit = {this.newSubmit}>

      <input type='text' name={'test1'} value={this.state.test1} onChange = {this.onChangeInput}

        />
      <input type='text' name={'test2'} value={this.state.test2}  onChange = {this.onChangeInput}

        />
      <button type='submit'> submit </button>
      </form>

    </div> 
    )
  }
}
export default ContactList;
2
  • Possible duplicate of Is React's setState asynchronous or something? Commented Jan 23, 2019 at 2:09
  • So one thing I did find was adding a call back to setstate but for some reason that’s not working for me either. Commented Jan 23, 2019 at 2:16

2 Answers 2

4

Try this one, take notice on the callback function of setState

import React, { Component } from 'react';



class ContactList extends Component {
  constructor(props){
    super(props);
    this.state = {
      name: '',
      test1:'',
      test2:'',
      newCtc:{},
      ctcList:[],
      arr: []
    }
  }

  async componentDidMount() {
    try{
      const result = await fetch('https://jsonplaceholder.typicode.com/users')
      const data = await result.json()
      this.setState({arr:data})

    }catch(err){
      console.log(err)
    }
  }


  onChangeInput = (e)=>{
    const target = e.target;
    const name = target.name;
    const value = target.value;

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

  newSubmit = (e) =>{
    e.preventDefault();

    this.setState(Object.assign(this.state.newCtc,{test1:this.state.test1, test2:this.state.test2}), ()=>{
        console.log('newctc', this.state.newCtc)
        this.addContact();            
    });

    }



    addContact = ()=>{
        let newCtcList = [...this.state.ctcList];
        newCtcList.push({...this.state.newCtc});
        console.log('newctc addcontact', this.state.newCtc);
        console.log('newctclist',newCtcList);

      this.setState({ ctcList: newCtcList }, ()=>{
        console.log(this.state.ctcList);
        this.clearInput();
      });

    };




    clearInput = ()=>{
      this.setState({test1:'',test2:''});
      this.setState(Object.assign(this.state.newCtc,{test1:'', test2:''}));
    };

  render() {


    return (
      <div>

      <input type = 'text' name = 'name' onChange = {this.onChangeInput}></input>



      <form onSubmit = {this.newSubmit}>

      <input type='text' name={'test1'} value={this.state.test1} onChange = {this.onChangeInput}

        />
      <input type='text' name={'test2'} value={this.state.test2}  onChange = {this.onChangeInput}

        />
      <button type='submit'> submit </button>
      </form>

    </div> 
    )
  }
}
export default ContactList;
Sign up to request clarification or add additional context in comments.

Comments

1

Here a problematic line

// newCtc is empty => so Object.assign, simply returns {test1: 'some value', test2: //  somevalue }
// this.setState then merges this into the array, so newCtc is not actually updated
// but the properties test1 and test2
this.setState(Object.assign(this.state.newCtc,{test1:this.state.test1, test2:this.state.test2}));
import React, { Component } from 'react';
import Contact from './Contact';
import TestData from './TestData';


class ContactList extends Component {
  constructor(props){
    super(props);
    this.state = {
      name: '',
      test1:'',
      test2:'',
      newCtc:{},
      ctcList:[],
      arr: []
    }
  }

  async componentDidMount() {
    try{
      const result = await fetch('https://jsonplaceholder.typicode.com/users')
      const data = await result.json()
      this.setState({arr:data})

    }catch(err){
      console.log(err)
    }
  }


  onChangeInput = (e)=>{
    const target = e.target;
    const name = target.name;
    const value = target.value;
    console.log(value)
    this.setState({
      [name]: value
    });
  }

  newSubmit = (e) =>{
    e.preventDefault();

    const ctcCopy = Object.assign({}, this.state.newCtc);

    this.setState({newCtc: Object.assign(ctcCopy, {
      test1: this.state.test1,
      test2: this.state.test2,
    })})


    console.log(this.state.newCtc)

    this.addContact();



    this.clearInput();
    console.log(this.state.newCtc);

    }


    // I would also copy this.state.newCtc
    addContact = ()=>{
      this.setState({ ctcList:[ ...this.state.ctcList, ...this.state.newCtc] });
      console.log(this.state.ctcList);
    };




    clearInput = ()=>{
      this.setState({test1:'',test2:''});
      const ctcCopy = Object.assign({}, this.state.newCtc);

      this.setState({newCtc: Object.assign(ctcCopy, {
        test1: this.state.test1,
        test2: this.state.test2,
      })})
    };

  render() {


    return (
      <div>
      <Contact firstName = {this.state.name} lastName='mcdaniel' phoneNumber = '585-721-3824' />
      <input type = 'text' name = 'name' onChange = {this.onChangeInput}></input>

      <TestData data={this.state.arr} />  


      <form onSubmit = {this.newSubmit}>

      <input type='text' name={'test1'} value={this.state.test1} onChange = {this.onChangeInput}

        />
      <input type='text' name={'test2'} value={this.state.test2}  onChange = {this.onChangeInput}

        />
      <button type='submit'> submit </button>
      </form>

    </div> 
    )
  }
}
export default ContactList;


Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.