我有一个字符串数组,我想将其作为列表呈现,带有彩色文本。用户可以使用按钮更改颜色。
为此,我构建了一个名为的组件,它接收一个数组,并使用数组的值和一个更改颜色的按钮呈现一个列表:
import React, { Component } from "react";
const renderArray = arr => (arr.map(value => (
<li>
{value}
</li>
)))
class List extends Component {
constructor(props) {
super(props);
this.state = {
color: 'red'
}
}
toggleColor = () => {
if (this.state.color === "red") {
this.setState({color: "blue"});
} else {
this.setState({color: "red"});
}
}
render() {
const style = {
color: this.state.color
};
return (
<div style={style}>
<ul>
{renderArray(this.props.array)}
</ul>
<button onClick={this.toggleColor}>Change color</button>
</div>
);
}
}
export default List;
使用以下方式调用List:
<List array={arr} />
并且arr:
const arr = ['one', 'two', 'three'];
在这里小提琴:Fiddle
但这对我来说似乎不对。每次颜色变化时,我都会通过调用renderArray()
来重新渲染整个数组。在这种情况下,它不是太糟糕,但如果renderArray()
更复杂会怎么样?
根据我的理解,我只需要在数组prop更改时创建一个新列表,这可以在getDerivedStateFromProps中执行(或者在不推荐使用的componentWillReceiveProps中执行...):
componentWillReceiveProps(nextProps)
{
const renderedArray = renderArray(nextProps.array);
this.setState({ renderedArray });
}
然后,在渲染时,使用this.state.renderedArray
显示列表。
但这似乎很奇怪,要在状态中存储渲染对象...... 有什么建议吗?
谢谢!
答案 0 :(得分:1)
1)React使用虚拟DOM的概念来计算内存中的实际差异,只有当它存在时,才能将差异渲染到DOM中
2)你可以帮助&#34;通过提供&#34;密钥&#34;来实现反应,以便更好地了解是否需要重新呈现列表/项目
3)您的代码componentWillReceiveProps
可能被视为不良做法,因为您正在尝试进行过早优化。重画速度慢吗?你有没有测量过它?
4)恕我直言:renderArray
方法没有意义,可以内联到List
组件
答案 1 :(得分:0)
通过使用虚拟DOM React有效地呈现DOM元素并检查更新是否需要发生,因此即使使用props渲染列表也可能不是问题。为了优化它,你可以做的是利用PureComponent
对状态和道具进行浅层比较,如果没有任何改变则不会导致重新渲染
import Reactfrom "react";
const renderArray = arr => (arr.map(value => (
<li>
{value}
</li>
)))
class List extends React.PureComponent { // PureComponent
constructor(props) {
super(props);
this.state = {
color: 'red'
}
}
toggleColor = () => {
if (this.state.color === "red") {
this.setState({color: "blue"});
} else {
this.setState({color: "red"});
}
}
render() {
const style = {
color: this.state.color
};
return (
<div style={style}>
<ul>
{renderArray(this.props.array)}
</ul>
<button onClick={this.toggleColor}>Change color</button>
</div>
);
}
}
export default List;