繁体   English   中英

React-native是否不应该仅渲染类似于React工作方式的更改组件?

[英]Shouldn't React-native render only changed components similar to how React works?

我是React领域的新手,但我对它的结构以及至少如何使用它来制作简单的Webapp相当熟悉,但这使我抓了好几个小时

我正在使用React-native制作井字游戏,目前仅在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和icon属性,并将它们变成完全静态的对象,并将板子更改为一个简单的布尔值,然后将其传递给第一个图块。 但是不,它仍然呈现了所有9个元素!

有人可以告诉我,React-native不应该只渲染与React相似的组件吗?

最近,我了解到,当设置新状态(或更改道具)时,此父组件的层次结构中的所有组件都会触发render函数。 这对于React是正确的,而不是特定于React-Native 这是因为React的shouldComponentUpdate()默认为true

这并不意味着实际上要重新渲染组件 React足够聪明,可以确定是否需要更新UI,这是称为“对帐”的过程的一部分。

也就是说,如果您有许多具有深层次结构的组件,则此行为可能会给JS线程带来一些压力。 如果遇到性能问题,您可以重写shouldComponentUpdate来执行自己的逻辑,或者仅继承React.PureComponent而不是docs中所说的React.Component

如果您确定某个特定组件在分析后运行缓慢,则可以将其更改为从React.PureComponent继承,该组件通过浅层支持和状态比较来实现shouldComponentUpdate()。 如果您确定要手工编写,可以将this.props与nextProps进行比较,并将this.state与nextState进行比较,然后返回false来告诉React可以跳过更新。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM