教程:React 简介 - 重新渲染整个集合而不是最近更改的元素
Tutorial: Intro to React - Rerendering the whole collection instead of the most recently changed element
我一直在通过官方“Tutorial: Intro to React”
完整代码可见here
提供了九个方格的棋盘。方块的状态 "lifted up" 进入游戏 class 以最小化有状态组件的数量。单击方块将更改所述游戏 class 中的状态。我观察到的是,现在每个方块都被重新渲染,而不仅仅是我点击的那个。
为了把握问题我统计了Square功能组件的return-函数的调用次数
有问题的代码行:
import React, {Component} from 'react'
function Square(props) {
return (
<button className="square" onClick={props.onClick}>
{props.value}
</button>
);
}
class Board extends React.Component {
renderSquare(i) {
return (
<Square
value={this.props.squares[i]}
onClick={() => this.props.onClick(i)}
/>
);
}
render() {
return (
<div>
<div className="board-row">
{this.renderSquare(0)}
{this.renderSquare(1)}
{this.renderSquare(2)}
</div>
<div className="board-row">
{this.renderSquare(3)}
{this.renderSquare(4)}
{this.renderSquare(5)}
</div>
<div className="board-row">
{this.renderSquare(6)}
{this.renderSquare(7)}
{this.renderSquare(8)}
</div>
</div>
);
}
}
export default class Game extends React.Component {
constructor(props) {
super(props);
this.state = {
squares: Array(9).fill(null),
xIsNext: true,
};
}
handleClick(i) {
const squares = this.state.squares.slice();
squares[i] = this.state.xIsNext ? "X" : "O";
this.setState({
squares: squares,
xIsNext: !this.state.xIsNext,
});
}
render() {
const squares = this.state.squares
return (
<div className="game">
<div className="game-board">
<Board
squares={squares}
onClick={i => this.handleClick(i)}
/>
</div>
</div>
);
}
}
index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import Game from './Game';
ReactDOM.render(<Game />, document.getElementById('react'));
我预计 React 只会重新渲染我点击的方块。
取而代之的是,在每次点击任意一个空闲方块后,所有九个方块都会重新呈现。
根据我对 React 的理解,其中一个有益的特性是虚拟 DOM,它能够决定哪些节点需要在 "real" DOM 上更新。 'state' 的全部目的不就是计算必须重新渲染屏幕的哪一部分吗?
我意识到当我改变 "Game" 的状态时,整个 "game component" 将被重新渲染。但这不正是应该避免的吗?如何最大限度地减少有状态组件的数量并保持良好的性能?在这种情况下,它只有 9 个方块重新渲染。但是想象一下我有一个 200x200 正方形的区域...
尝试使用 shouldComponentUpdate
实现 Square
class Square extends React.Component {
shouldComponentUpdate(nextProps) {
return this.props.value !== nextProps.value;
}
render() {
const { value, onClick } = this.props;
return (
<button className="square" onClick={onClick}>
{value}
</button>
);
}
}
我一直在通过官方“Tutorial: Intro to React”
完整代码可见here
提供了九个方格的棋盘。方块的状态 "lifted up" 进入游戏 class 以最小化有状态组件的数量。单击方块将更改所述游戏 class 中的状态。我观察到的是,现在每个方块都被重新渲染,而不仅仅是我点击的那个。
为了把握问题我统计了Square功能组件的return-函数的调用次数
有问题的代码行:
import React, {Component} from 'react'
function Square(props) {
return (
<button className="square" onClick={props.onClick}>
{props.value}
</button>
);
}
class Board extends React.Component {
renderSquare(i) {
return (
<Square
value={this.props.squares[i]}
onClick={() => this.props.onClick(i)}
/>
);
}
render() {
return (
<div>
<div className="board-row">
{this.renderSquare(0)}
{this.renderSquare(1)}
{this.renderSquare(2)}
</div>
<div className="board-row">
{this.renderSquare(3)}
{this.renderSquare(4)}
{this.renderSquare(5)}
</div>
<div className="board-row">
{this.renderSquare(6)}
{this.renderSquare(7)}
{this.renderSquare(8)}
</div>
</div>
);
}
}
export default class Game extends React.Component {
constructor(props) {
super(props);
this.state = {
squares: Array(9).fill(null),
xIsNext: true,
};
}
handleClick(i) {
const squares = this.state.squares.slice();
squares[i] = this.state.xIsNext ? "X" : "O";
this.setState({
squares: squares,
xIsNext: !this.state.xIsNext,
});
}
render() {
const squares = this.state.squares
return (
<div className="game">
<div className="game-board">
<Board
squares={squares}
onClick={i => this.handleClick(i)}
/>
</div>
</div>
);
}
}
index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import Game from './Game';
ReactDOM.render(<Game />, document.getElementById('react'));
我预计 React 只会重新渲染我点击的方块。
取而代之的是,在每次点击任意一个空闲方块后,所有九个方块都会重新呈现。
根据我对 React 的理解,其中一个有益的特性是虚拟 DOM,它能够决定哪些节点需要在 "real" DOM 上更新。 'state' 的全部目的不就是计算必须重新渲染屏幕的哪一部分吗?
我意识到当我改变 "Game" 的状态时,整个 "game component" 将被重新渲染。但这不正是应该避免的吗?如何最大限度地减少有状态组件的数量并保持良好的性能?在这种情况下,它只有 9 个方块重新渲染。但是想象一下我有一个 200x200 正方形的区域...
尝试使用 shouldComponentUpdate
Square
class Square extends React.Component {
shouldComponentUpdate(nextProps) {
return this.props.value !== nextProps.value;
}
render() {
const { value, onClick } = this.props;
return (
<button className="square" onClick={onClick}>
{value}
</button>
);
}
}