javascript - 列表孩子没有正确更新?(反应/预演)
问题描述
我有以下组件
import {h, Component} from 'preact'
import {getPersons} from '../../lib/datalayer'
import Person from '../person'
import {SearchInput} from '../search'
export default class Persons extends Component {
state = {
allPersons: [],
persons: [],
search: ''
}
async fetchData () {
try {
const allPersons = await getPersons()
this.setState({allPersons: allPersons.slice(), persons: allPersons.slice()})
} catch (error) {
....
}
}
constructor (props) {
super(props)
this.state = {
allPersons: [],
persons: [],
search: ''
}
this.fetchData()
}
onSearchInput = (search) => {
if (search === '') {
this.setState({search: search, persons: this.state.allPersons.slice()})
} else {
const persons = this.state.allPersons.filter(p => p.name.toLowerCase().includes(search.toLowerCase())).slice()
this.setState({search: search, persons: persons)})
}
}
render () {
const {persons} = this.state
return (
<div>
<SearchInput onInputChange={this.onSearchInput} placeHolder={'filter: name'} />
{persons.map(p => <Person person={p} />)}
</div>
)
}
}
该页面呈现人员列表,顶部有一个过滤器。过滤器似乎工作正常,我通过控制台进行了测试。结果很好
问题是,如果我的列表包含对象:
[{name: 'thomas'}, {name: 'john'}, {name: 'marcus'}, {name: 'usa'}]
我在搜索输入中写道:“我们”
过滤器工作正常,结果是:
[{name: 'marcus'}, {name: 'usa'}] \\ (the expected result)
在页面中呈现此对象
[{name: 'thomas'}, {name: 'john'}] \\ (wrong, this are the two first elements of the list)
如果我搜索:'joh'
过滤器的结果是
[{name: 'john'}] \\ (this is fine)
并且页面只呈现
[{name: 'thomas'}] \\ (the first element in the list)
看起来渲染的元素数量很好,但是列表的子元素的内容没有重新渲染。
我的代码有什么问题?
解决方案
React 使用keys
列表的子项来确定哪些项目发生了变化,哪些项目保持不变。由于您没有指定key
on person,因此它index
是关键。
当索引是关键时,您可以看到如何将列表缩短为两个项目,从而显示列表中的前两个项目(现在缺少其他索引)。为了解决这个问题,你必须给这个人一个唯一的标识符作为键。
从您的对象中,假设name
是唯一的(通常不是):
{persons.map(p => <Person person={p} key={p.name} />)}
推荐阅读
- javascript - 为什么 Javascript DOM 有这种奇怪的行为?
- java - 如何解决 SAXParseException: cvc-elt.1 -> 'bpm-platform'?
- anaconda - 找不到 Anaconda 导航器或 Anaconda 提示符
- javascript - 这种选择排序的实现有什么问题?
- c# - 无法使用 SendGrid WebApi lib 发送电子邮件
- php - 通过 PHP cURL 500 服务器错误的 REST API 调用
- php - 获取某些目录和子目录中所有文件的部分路径
- c++ - 将 mmap 内存用于开销非常低的循环缓冲区
- c# - Handlebars.Net If 条件助手
- xml - 如何使用 VBScript 将 DOCTYPE 属性设置为 XML DOM?