渲染与array.map反应

时间:2018-03-30 17:19:19

标签: reactjs

我有一个字符串数组,我想将其作为列表呈现,带有彩色文本。用户可以使用按钮更改颜色。

为此,我构建了一个名为的组件,它接收一个数组,并使用数组的值和一个更改颜色的按钮呈现一个列表:

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显示列表。

但这似乎很奇怪,要在状态中存储渲染对象...... 有什么建议吗?

谢谢!

2 个答案:

答案 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;