在React Native中渲染子组件

时间:2017-08-10 19:35:19

标签: javascript android react-native render

我正在使用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。

0 个答案:

没有答案