Ansh Varun
Ansh Varun

Reputation: 100

Can't access this.state in other function

class Uploader extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
          data: '',
          name:'',
          loading: false
        }
    }
}

This is the function where I load value in this.state.load

 onChange(e) {
    let files = e.target.files;
    let reader = new FileReader();
    reader.readAsDataURL(files[0]);
    this.state.name = files[0].name;

    reader.onload = ((e) => {
        console.log("file is",e.target.result);
        const formData = {data: e.target.result};
        this.state.data = formData;
        this.setState({data: this.state.data});
        console.log(this.state.data); // here it gives value whats inside file
    });
    this.setState({'name': this.state.name});
    console.log(this.state.data)  // here it doesn't print anything
}

calling it in any function:

onUpload() {
    console.log(this.state.data);
}

It doesn't render. It gives: "error state undefined". How can I use this.state.data in other functions or other scopes of code, any other way to call this value or need of this correction ????

Upvotes: 0

Views: 935

Answers (4)

Imran
Imran

Reputation: 530

Bind your method with the class, otherwise this will be undefined

    1.
class Uploader extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
          data: '',
          name :'',
          loading : false
        }

        this.onChange = this.onChange.bind(this);
    }
}

Or use arrow function in class properties if you have support for it.

  1. class Uploader extends React.Component {
    
        constructor(props) {
            super(props);
            this.state = {
              data: '',
              name :'',
              loading : false
            }
        }
    
        onChange = () => {}
    }
    

Upvotes: 1

Babak Yaghoobi
Babak Yaghoobi

Reputation: 1985

change you function to this:

onChange(e){
    const that = this ; // add this
    let files = e.target.files;
    let reader =new FileReader();
    reader.readAsDataURL(files[0]);
    // don't set directly value to state !
    // this.state.name = files[0].name;
    this.setState({name: files[0].name}, function() {
       console.log(that.state.name)  // here it doesn't print anything
    });

    reader.onload = ((e) => {
        console.log("file is",e.target.result);
        //const formData = { data : e.target.result }
        //this.state.data = formData; 
        // Use setState callback to get state result 
        that.setState({data : e.target.result}, function() {
          console.log(that.state.data) // here it gives value whats inside file
        });

    });


}

Upvotes: 0

Atin Singh
Atin Singh

Reputation: 3690

Making a function (except arrow function) creates it's own instance of this. So there's no state object inside your function. To deal with this problem you have two ways -

Use an arrow function -

using an arrow function does not create it's own instance of this

 onUpload = () => {
    console.log(this.state.data) 
}

Bind your function's this to class's this

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

Hope this helps you. :)

Upvotes: 4

Use bind in constructor:

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

Or use arrow function:

onChange = (e) => {
  ...
}

Upvotes: 1

Related Questions