我是React场景的新手,但我对它的结构非常熟悉,至少如何使用它制作简单的webapps但是这让我头疼了好几个小时
我正在使用React-native制作Tic Tac Toe,我目前只在Android上进行实验。这些是我的代码中的部分,我认为这解释了我的情况
import Tile from "./Tile"
export default class Playground extends React.Component {
constructor(props) {
super(props)
this.state = {
board: [["?", "?", "?"], ["?", "?", "?"], ["?", "?", "?"]],
turn: "X"
}
}
move(x, y) {
if (this.state.board[x][y] == "?") {
var currentTurn = this.state.turn
var currentBoard = this.state.board
currentBoard[x][y] = this.state.turn
this.setState({board: currentBoard});
//this.isGameOver(x, y);
}
}
isGameOver(x, y) {
//Game Over Test
}
render() {
return (
<View style={styles.container}>
<View style={styles.row}>
<Tile onPress={this.move.bind(this, 0, 0)} icon={this.state.board[0][0]}/>
<Tile onPress={this.move.bind(this, 0, 1)} icon={this.state.board[0][1]}/>
<Tile onPress={this.move.bind(this, 0, 2)} icon={this.state.board[0][2]}/>
</View>
<View style={styles.row}>
<Tile onPress={this.move.bind(this, 1, 0)} icon={this.state.board[1][0]}/>
<Tile onPress={this.move.bind(this, 1, 1)} icon={this.state.board[1][1]}/>
<Tile onPress={this.move.bind(this, 1, 2)} icon={this.state.board[1][2]}/>
</View>
<View style={styles.row}>
<Tile onPress={this.move.bind(this, 2, 0)} icon={this.state.board[2][0]}/>
<Tile onPress={this.move.bind(this, 2, 1)} icon={this.state.board[2][1]}/>
<Tile onPress={this.move.bind(this, 2, 2)} icon={this.state.board[2][2]}/>
</View>
</View>
)
}
}
当然还有瓷砖的代码
export default class Tile extends React.Component {
constructor(props) {
super(props)
}
rand() {
return Math.random() * 256;
}
randColor() {
return "rgb(" + this.rand() + " ," + this.rand() + " ," + this.rand() + ")";
}
determineIcon() {
if (this.props.icon == "X") {
return (<Text>O</Text>)
} else if (this.props.icon == "O") {
return (<Text>X</Text>)
} else {
return null;
}
}
render() {
console.log("Things are happening!")
return (
<TouchableHighlight onPress={this.props.onPress} underlayColor={this.randColor()}>
<View style={[styles.square, {backgroundColor: this.randColor()}]}>
{this.determineIcon()}
</View>
</TouchableHighlight>
)
}
}
所以我最初注意到的是每次我点击一个瓷砖并且它已成功更改为X所有颜色再次重新生成,这让我意识到我的应用程序正在重新渲染所有内容。
所以我认为这是随机函数的错误,并决定将所有正方形都设为橙色,但我想知道它是否仍在重新渲染所有内容或只是我按下的磁贴,所以我把控制台日志放到看看渲染发生了多少次,令我沮丧的是它发生了9次。
我最终删除了最后8个图块中的onPress和图标属性,并将它们转换为完全静态的对象,并将板更改为我传递给第一个图块的简单布尔值。但不,它仍然再次呈现所有9个元素!
有人可以向我解释一下,React-native渲染不应该只更改与React工作方式相似的组件吗?
答案 0 :(得分:4)
最近我了解到,当设置新状态时(或更改道具时),此父组件层次结构中的所有组件都将触发render
功能。这适用于React
,而不是React-Native
特有的;这是因为React的shouldComponentUpdate()
默认为true
。
这并不意味着组件实际上会再次重新渲染。 React非常聪明,可以确定是否需要更新UI,这是一个名为&#34; Reconciliation&#34;的过程的一部分。
也就是说,如果你有很多具有深层次结构的组件,这种行为可能会给JS线程带来一些压力。如果您遇到性能问题,可以覆盖shouldComponentUpdate
来执行自己的逻辑,或者只是继承React.PureComponent
而不是React.Component
,如docs中所述:
如果您在分析后确定特定组件的速度很慢,则可以 将其更改为从实现的React.PureComponent继承 shouldComponentUpdate()具有浅的prop和状态比较。如果 你有信心想要手工编写,你可以比较 this.props with nextProps和this.state with nextState并返回 false告诉React可以跳过更新。