React child state update based on parent's prop change

时间:2017-08-30 20:03:37

标签: javascript reactjs

I am trying to implement minesweeper with React. I have a Header component (not shown) where the dimensions and the number of bombs can be changed so the App component state (setTimeout(), setTimeout() and TypeError: child[i] is undefined) will be updated, and these values will be sent down to the sizeX component as props.

My problem is that the sizeY component state is dependent on bombNumber component's props and when the Tablemethod gets invoked on prop updates it uses the updated Table and App props (which is good of course) but for some reason it uses the previous value of the createTable() prop.

Is this the right approach? If so what did I miss?

sizeX

Table.js

sizeY

Update:

The console log here prints the right values if I change the state, but the child will use the old value for bombNumber.

class App extends Component {
  constructor (props) {
  super(props);

  this.state = {
    sizeX: DEFAULT_SIZE,
    sizeY: DEFAULT_SIZE,
    maxBombNumber: DEFAULT_BOMB_NUMBER,
    bombNumber: DEFAULT_BOMB_NUMBER

  }

  updateSize (val, side) {
    this.setState({[side]: val}, function () {
      this.setState({maxBombNumber: this.calculateMaxBombNumber()}, function () {
        if (this.state.maxBombNumber < this.state.bombNumber) {
          this.setState({bombNumber: this.state.maxBombNumber}, function (){
          });
        }
      });
    });
  }

  render() {
    return (
      <div className="App">
        <Table 
          sizeX={this.state.sizeX}
          sizeY={this.state.sizeY}
          bombNumber={this.state.bombNumber}
        />
      </div>
    );
  }
}

2 个答案:

答案 0 :(得分:2)

Try to wrap all setState calls in one:

1

UPD:

import requests
url ="http://someapi/v1/auth"
payload = {'username': '', 'password': ''}
s1 = requests.post(url, headers={"content-type":"application/x-www-form-urlencoded"}, data=json.dumps(payload))  
print s1.status_code

When Table component get new props from parent App –> componentWillReceiveProps execute and this.createTable() method use previous values not that in nextProps. In this way you should give it properly by arguments to createTable for example. Check this example.

UPD 2:

It will be better to make Table component – dump (stateless) and use state only in parent component App. Just move import React from 'react'; import { View, Text, } from 'react-native'; export default class Hello extends React.Component { render() { return { <View> <Text>Hola desde Hello.js</Text> </View> } } } method to App and it will be enough.

Or you can call createTable inside render method of Table.

答案 1 :(得分:0)

我认为您的问题是setState是异步调用,因此您使用的this.state不会更新。有关将setState与函数一起使用的详细信息,请参阅此文章。 https://medium.freecodecamp.org/functional-setstate-is-the-future-of-react-374f30401b6b

我认为这会让你得到你想要的东西:

updateSize(val, side) {
    this.setState({ [side]: val }, function () {
        this.setState({ maxBombNumber: this.calculateMaxBombNumber() }, this.setState(function (state) {
            if (state.maxBombNumber < state.bombNumber) {
                this.setState({ bombNumber: state.maxBombNumber }, function () {
                    console.log(state);
                });
            }
        }));
    });
}