React: setState does not make results just as expected(not working?)

My project is Cordova + React(es6). I have a few problem with using the setState().

the data that is passed to state is not empty. But, passing the data to state, I receive results State is empty.

My project's env(package.json):

{
  "name": "MYAPP",
  "version": "1.0.0",
  "description": "this is front of simula's app",
  "main": "gulpfile.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "browserify ./www/jsx/app.jsx -t babelify -o ./www/js/app.js"
  },
  "author": "maki",
  "license": "ISC",
  "dependencies": {
    "babel-preset-es2015": "^6.13.2",
    "browserify": "^13.1.0",
    "gulp": "^3.9.1",
    "history": "^4.2.0",
    "material-design-icons": "^2.2.3",
    "material-ui": "^0.15.4",
    "rd3": "^0.7.2",
    "react": "^15.3.0",
    "react-d3": "^0.4.0",
    "react-dom": "^15.3.1",
    "react-motion": "^0.4.4",
    "react-router": "^2.7.0",
    "react-swipeable-views": "^0.7.0",
    "react-tap-event-plugin": "^1.0.0",
    "vinyl-source-stream": "^1.1.0"
  },
  "devDependencies": {
    "babel-cli": "^6.11.4",
    "babel-plugin-transform-class-properties": "^6.11.5",
    "babel-preset-react": "^6.11.1",
    "babel-preset-stage-1": "^6.13.0",
    "babelify": "^7.3.0",
    "gulp-sass": "^2.3.2",
    "jquery": "^3.1.0"
  }
}

And my code:

export default class SomeCard extends React.Component {
  constructor(){
    super();

    this.state = {
      data_source: []
    }
  }

  componentDidMount(){
    const {name, data} = this.props.data;
    if(name == 'AAA'){
      let values_a = data.map((tmp_data) =>{
        let date = new Date(tmp_data.date);
        return {
          x: date,
          open: tmp_data.open,
          high: tmp_data.high,
          low: tmp_data.low,
          close: tmp_data.close
        };
      });
      let final_tmp_data = [
        {
          name: name,
          values: values_a
        }
      ];
      console.log(final_tmp_data);  //NOT EMPTY
      this.setState({data_source: final_tmp_data});
      console.log(data_source);     //NOT EMPTY
    }else if(name == 'BBB'){
      let values_b = data.map((tmp_data) => {
        let date = new Date(tmp_data.date);
        let tmp_date = date.getFullYear();
        return {
          "x": String(tmp_date),
          "y": tmp_data.value
        };
      });
      let final_cash_data = [
        {
          "name": name,
          "values": values_b
        }
      ];
      console.log(final_cash_data);          //NOT EMPTY
      this.setState({data_source: final_cash_data});
      console.log(this.state.data_source);   //EMPTY!!!!!!!!
    }
  .....
}

What should I do???

Answers:

Answer

React setState() is an async operation so it does not deliver the result immediately after it is called in you code. You can access the updated state you if add console.log(this.state.data_source); inside your render() method which is only called when this.setState() completes.

Have a looke a the React docs: https://facebook.github.io/react/docs/component-api.html#setstate

setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value. There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.

setState() will always trigger a re-render unless conditional rendering logic is implemented in shouldComponentUpdate().

Answer

In addition to Piotr'a answer, setState can be passed a callback which is called with the new state, e.g.;

  this.setState({data_source: final_cash_data}, function(newState){
    console.log(newState.data_source)
  });

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.