Array.map是否重用React组件的实例?

时间:2017-03-27 02:51:20

标签: javascript arrays reactjs

我使用Array.map在React中渲染多个项目时遇到了奇怪的症状。 在下面的代码中,filtered1和filtered2应该显示相同的结果。但是,结果不同。

似乎Array.map重用了React组件的实例。 这是Array.map的正确行为吗?

您可以看到完整的来源和演示here

class Row extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            id: props.data.Id,
            isTrue: props.data.IsTrue
        }
    }
    render () {
        const {data} = this.props
            return (
            <tr>
                <td>{data.Id}</td>
                <td>{data.IsTrue ? 'true' : 'false'}</td>
                <td style={{backgroundColor:(this.state.isTrue ? 'green' : 'red')}}>{this.state.id}</td>
                <td style={{backgroundColor:(this.props.data.IsTrue ? 'green' : 'red')}}>{this.props.data.Id}</td>
            </tr>
        )
    }
}
class App extends React.Component {
    constructor(props) {
        super(props)
        this.state = { filter: 'all' }
    }
    render () {
        const data = [
            {"Id":"1","IsTrue":true},{"Id":"2","IsTrue":true},{"Id":"3","IsTrue":false},{"Id":"4","IsTrue":false},{"Id":"5","IsTrue":true},
            {"Id":"6","IsTrue":true},{"Id":"7","IsTrue":false},{"Id":"8","IsTrue":true},{"Id":"9","IsTrue":true},{"Id":"10","IsTrue":false}]

        const filtered1 = 
            data
            .filter(x => this.state.filter == 'all' || x.IsTrue)
            .map((item, index) => (<Row key={index} data={item} />))

        const filtered2 = 
            data
            .map((item, index) => (<Row key={index} data={item} />))
            .filter(x => this.state.filter == 'all' || x.props.data.IsTrue)

        return (
            <div>
                <select value={this.state.filter} onChange={e => this.setState({filter: e.target.value})}>
                    <option value='all'>All</option>
                    <option value='ts'>Trues</option>
                </select>
                <div>
                  <span>
                    <h1>filter -> map</h1>
                    <table>
                      <thead>
                        <tr>
                          <th>Id</th>
                          <th>IsTrue</th>
                          <th>State Value</th>
                          <th>Props Value</th>
                        </tr>
                      </thead>
                      <tbody>
                        {filtered1}
                      </tbody>
                    </table>                  
                  </span>
                  <span>
                    <h1>map -> filter</h1>
                    <table>
                      <thead>
                        <tr>
                          <th>Id</th>
                          <th>IsTrue</th>
                          <th>State Value</th>
                          <th>Props Value</th>
                        </tr>
                      </thead>
                      <tbody>
                        {filtered2}
                      </tbody>
                    </table>                  
                  </span>
                </div>
            </div>
        )
    }
}

1 个答案:

答案 0 :(得分:2)

不要使用数组的索引作为键;使用有关item的一些独特信息,例如:

key={`${item.Id}:${item.IsTrue}`}

通过使用数组的索引,React认为项目是相同的,即使它们是不同的。 React不会查看项目内部,它只查看键值。如果键是相同的,它会重用&#34; old&#34;组件无需重新渲染。

如需进一步阅读,请参阅Lists and Keys的文档。您会注意到他们没有使用索引作为关键字,除非在一个场景中,他们明确警告:

  

仅在项目没有稳定ID时执行此操作