我正在使用React Native和React Navigation来构建一个简单的应用程序 . 我有基本结构使用存根状态但我有通过回调和重新渲染更改状态的问题 .

在我的屏幕中,我有简单的启动按钮

`<View style={styles.buttonContainer}>
   <TouchableOpacity 
     style={[myStyles.buttonStyle, { backgroundColor: color }]} 
     onPress={() => handlePress(button.title)}
   >
     <Text style={myStyles.textStyle}>{button.title}</Text>
   </TouchableOpacity>
 </View>`

问题:

更新我的父组件状态后,我的子组件不会立即呈现以匹配状态更改 . 我知道当父状态发生变化时,React会重新渲染所有子组件吗?

相反,我必须返回到上一个屏幕并再次导航到我的按钮屏幕,以查看按钮的颜色和文本是否已正确更改 .

我已经读过需要一个componentWillReceiveProps(nextProps)处理程序,但我不知道如何使用它 . 我把一个console.log('nextProps',nextProps)放在里面,但它没有被解雇 .

从导航角度来看,Root组件位于索引[0]上,而我的按钮视图位于索引[3],因此它是根目录中的第3个屏幕 .

编辑1:添加代码

myButton屏幕:

export class TeamsScreen extends React.Component {
  static navigationOptions = ({ navigation }) => ({
    title: `${navigation.state.params.game.name}: Select Team`,
    headerTintColor: 'white',  
    headerStyle: {
      backgroundColor: 'black',
    },
    headerVisible: true
  })

componentWillReceiveProps(nextProps) {
  console.log('nextProps', nextProps);
}

render() {
  const { navigate, setParams } = this.props.navigation;
  const { game, player, setGameState } = this.props.navigation.state.params;
  const color = game.status === 'Start' ? 'green' : 'red';
  const index = game.indexOf(player);
  const status = game.status;
  console.log('index', index);
  console.log('status', status);

return (
  <View style={styles.container}>
    <View style={styles.buttonContainer}>
      <TouchableOpacity 
      style={[myStyles.buttonStyle, { backgroundColor: color }]} 
      onPress={() => setGameState(index, status)}
      >
        <Text style={myStyles.textStyle}>{game.status}</Text>
      </TouchableOpacity>
    </View>
    <View style={styles.buttonContainer}>
      <Button
        onPress={() => navigate('ChangeDriverScreen', { team, game })}
        title='Change Driver'
       />
    </View>
    <View style={{ marginTop: 40, marginBottom: 20 }}>
      <Text style={{ fontSize: 16, color: 'white', alignSelf: 'center' }}>Teams</Text>
    </View>
    <View style={{ height: 250 }}>
      <FlatList
        data={player.teams}
        renderItem={({item}) =>
          <View style={styles.buttonContainer}>
            <Button
              onPress={() => navigate('TeamSelectedStartScreen', { team: item })}
              title={item.name}
            />
          </View>}
        keyExtractor={item => item.name}
      />
    </View>
    <Image
      style={{ alignSelf: 'center', justifyContent: 'flex-end', height: 75, width: 250, resizeMode: 'stretch'}}
      source={require('./images/icons/playerPlaceholder.png')}
    />
  </View>
)}}

然后回调的onPress函数:

setGameState = (gameIndex, status) => {
  console.log('setGameState', gameIndex, status);
  console.log('gameStateBefore', this.state.game);
  const newGameState = this.state.game.map(t => {
    console.log(this.state.game.indexOf(t));
    if (this.state.game.indexOf(t) === gameIndex) {
      const newStatus = status === 'Start' ? 'Stop' : 'Start';
      t.status = newStatus; /*eslint no-param-reassign: "off"*/
      console.log('inside if', t.status);
      console.log('inside if game', t);
      return t;
    }
    return t;
  });

  console.log('new Game State', newGameState);

  this.setState(() => ({
    game: newGameState
  }));
}

因此setState方法有效(因为重新导航回屏幕3显示正确的状态,但核心问题是当从屏幕0调用setState时如何立即重新呈现屏幕3 .