我可以在不触发重新渲染的情况下更改祖父母内联CSS吗?

时间:2017-04-21 11:19:33

标签: css reactjs

我正在尝试通过单击10,000个孙子中的一个来更改组件的内联CSS。

World将回调函数传递给其子Terrain。此组件创建一个100乘100子组件Tile的网格。每个人都有一个position属性,可以传递给回调,通知World更改其CSS,以便将点击的Tile移动到屏幕的中心。

以下代码有效,但速度很慢。显然,setState always triggers a re-render。由于我的World有10,000个Tile个孙子,因此World在屏幕上移动的响应是滞后的。

我已经确认延迟是由元素数量引起的,因为创建只有4个Terrain子项的Tile会使点击响应变得非常活泼。

由于setState会触发重新渲染,我还可以根据点击的World更改Tile的内嵌CSS吗?

class World extends Component {
    // this function is passed down to Terrain
    changePosition( newPosition ) {
        this.setState({
            position : newPosition
        });
    }

    convertPosition( position ) {
        let x = ( this.tileSize / 2 ) + ( position.x * this.tileSize );
        let y = ( this.tileSize / 2 ) + ( position.y * this.tileSize );
        let translate = 'translate( ' + -x + 'px, ' + -y + 'px )';
        return translate;
    }

    render() {
        let terrainSize = {
            x : 100,
            y : 100
        };
        let style = {
            transform : this.convertPosition( this.state.position ),
            width     : terrainSize.x * this.tileSize,
            height    : terrainSize.y * this.tileSize
        };
        return (
            <div className="world" style={ style }>
                <Terrain
                    size={ terrainSize }
                    tileSize={ this.tileSize }
                    onTileClick={ this.changePosition.bind( this ) }
                />
            </div>
        );
    }
}
class Terrain extends Component {
    tileClicked( position ) {
        this.props.onTileClick( position );
    }

    render() {
        let tiles = [];
        // create 100 * 100 Tiles
        for( let x = 0; x < this.props.size.x; ++x ) {
            for( let y = 0; y < this.props.size.y; ++y ) {
                let position = {
                    x : x,
                    y : y
                };
                tiles.push(
                    <Tile
                        key={ x + ',' + y }
                        position={ position }
                        size={ this.props.tileSize }
                        onClick={ () => this.tileClicked( position ) }
                    />
                );
            }
        }
        return (
            <div className="terrain">
                { tiles }
            </div>
        );
    }
}
class Tile extends Component {
    render() {
        let style = {
            position : 'absolute',
            top      : this.props.position.y * this.props.size,
            left     : this.props.position.x * this.props.size,
            width    : this.props.size,
            height   : this.props.size
        };
        return (
            <div className="tile" onClick={ this.props.onClick } style={ style }></div>
        );
    }
}

0 个答案:

没有答案