当其属性更改时,如何重新渲染反应组件?

时间:2020-02-18 23:00:29

标签: reactjs react-native

抱歉,这是一个菜鸟问题。我正在尝试建立一个带有大厅的反应式多人游戏,以显示您的对手是谁。问题在于,即使代表对手的道具更新了,该组件也不会重新渲染,即使控制台日志显示我道具已经更改(并且render()被调用了?)。我的代码中的一些代码片段如下:

在Lobby.js中:

export default class Lobby extends Component {
  render() {
    console.log('In Lobby, opponents = ' + this.props.opponents);
    return(
      <View style={{ flex: 1, justifyContent: "center", alignItems: 'center' }}>
        <Text>Welcome to the lobby { this.props.username }!</Text>
        <Text>Opponents: { this.props.opponents }</Text>
        ... more text and buttons ...
      </View>
    );
  }
}

正如我所说,我可以在控制台中看到this.props.opponents确实发生了变化,但是屏幕似乎并未重新渲染该<Text>组件。我最初以为这可能是因为this.props.opponents设置为我的主要组件状态的opponents值,但是控制台日志似乎将其揭穿了。

我在SO上看过这里,发现了向我的组件中添加shouldComponentUpdate()componentDidUpdate()的建议,但 nextProps参数实际上总是与{{1 }} 。即如果我添加:

this.props

对于我来说,这实际上并没有返回True ,即使该道具肯定在改变。 (我也不知道我实际上想要在componentDidUpdate()中使用什么代码,因为我只想重新渲染它)。它只是表明,是的,道具是不同的,但是shouldComponentUpdate(nextProps) { console.log('this.props.opponents=' + this.props.opponents + '; ' + 'nextProps.opponents=' + nextProps.opponents); return this.props.opponents != nextProps.opponents; } nextProps.opponents都已更改为相同的新值(即“ TestUser”)。

我真的很茫然。预先感谢。

编辑:添加了我的代码的简化版本。

App.js:

this.props.opponents

在Main.js中:

import React, { Component } from 'react';

import Main from './components/Main';

export default function App() {
  return (
    <Main/>
  )
}

在Lobby.js中:

import React, { Component } from 'react';
import { View } from 'react-native';

import Lobby from './Lobby';

export default class Main extends Component {
  constructor(props) { 
    super(props);

    this.state = { 
      opponents: [], // array of strings of other users' usernames
      in_lobby: true // whether user is in lobby or not
    };

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

  testClientJoin() {
    console.log('Called testClientJoin().');
    let currentOpponents = this.state.opponents;
    currentOpponents.push('TestUser');
    this.setState({
      opponents: currentOpponents
    });
  }

  render() {
    return(
      <View style={{ flex: 1}}>
        {
          this.state.in_lobby &&
          <Lobby
            opponents={this.state.opponents}
            testClientJoin={this.testClientJoin}
          />
        }
      </View>
    );
  }
}

所以。当我点击添加测试对手的按钮时,控制台会记录

import React, { Component } from 'react';
import { View, Button, Text } from 'react-native';

export default class Lobby extends Component {
  render() {
    console.log('Opponents prop = ' + this.props.opponents);
    return(
      <View style={{ flex: 1, justifyContent: "center", alignItems: 'center' }}>
        <Text>Welcome to the lobby!</Text>
        <Text>Your opponents are {this.props.opponents}.</Text>
        <Button
          title='Add test opponent'
          onPress={this.props.testClientJoin}
        />
      </View>
    );
  }
}

表明道具确实已经更新。 但是,实际上并没有反映出这一变化,直到我强制进行一些更新(即,由于我正在使用expo,所以我只是再次保存了文件,最后我看到文本出现在手机上了。我确定我只是个白痴,但很想知道如何获得所需的文本组件更新行为。

1 个答案:

答案 0 :(得分:1)

好吧,我找到了问题的答案,如果有人发现,我会离开这里。我要做的是以下事情:

Main.js: 与其直接将this.state.opponents作为道具传递给<Lobby>,不如传递此数组的副本

render() {
  <Lobby
    testClientJoin={this.testClientJoin}
    opponents={ [...this.state.opponents] }
  />

这具有所需的结果。因此,故事的寓意是,不要尝试将数组状态从父级直接传递给子级组件。