所以,我有一个数组,我有2个组件(子和父),我遍历父组件内的数组,我渲染子组件,我从数组中给它们attrs(道具)。
子组件的attrs(props)递增和递减。
父组件可以将新项添加到数组中并重新渲染。
问题:为什么chid它使用.push()渲染,而使用.unshift()渲染不好。使用concat和[newItem,... oldArray]一切都还可以,但是当他们在数组前面添加项目时,同样的事情还不错?另外如何正确地将.unshift()新项目(评论,计数器,图像,帖子,例如任何东西)放入状态,以便首先渲染?
PS:React,Infero和Aurelia也会出现这种情况。
PPS:我的反应更多,也许我对待Mithril的vnode并不是我想的那样。const root = document.getElementById('root')
var data = [0, 12, -10, 1, 0]
class app {
oninit(vnode){
vnode.state.data = data
}
oncreate(vnode) {
vnode.state.addCounter = function(e){
vnode.state.data.unshift(1)
}
}
view(vnode){
if(vnode.state.data){
return([
m('button',{onclick: vnode.state.addCounter},'add another counter'),
vnode.state.data.map((e,i)=>{
return(
m(Counter, {data: e, key: i})
)
})
])
}
}
}
class Counter {
oninit(vnode){
vnode.state.data = vnode.attrs.data
vnode.state.increment = function(e){
vnode.state.data = vnode.state.data + 1
}
vnode.state.decrement = function(e){
vnode.state.data = vnode.state.data - 1;
}
}
view(vnode){
return(
m('p',{style: 'display:inline;margin: 10px;'},[
m('b',{onclick: vnode.state.increment, style:'cursor: pointer'}, '+'),
m('i', vnode.state.data),
m('b',{onclick: vnode.state.decrement, style:'cursor: pointer'}, '-')
])
)
}
}
m.mount(root, app)
答案 0 :(得分:0)
错误是由key
引起的。在渲染子项时使用数组索引作为键:
vnode.state.data.map((e,i)=>{
return(
m(Counter, {data: e, key: i})
)
})
简单的解决方案是使用正确的密钥,在这种情况下,唯一有意义的是传递给孩子的数字:
vnode.state.data.map((number)=>{
return(
m(Counter, {data: number, key: number})
)
})
小提琴:https://jsfiddle.net/6kh0ggrb/
通常使用数组索引作为键是一个坏主意(在任何键控库/框架中包括Mithril.js),并且您的用例就是一个很好的例子。
让我们一步一步地看看:
1:设置
您从数组[0, 12, -10, 1, 0]
开始,并为数组中的相应数字渲染Counter
。新组件的键为0到4。
------------------------
| key | number | shows |
------------------------
| 0 | 0 | 0 |
| 1 | 12 | 12 |
| 2 | -10 | -10 |
| 3 | 1 | 1 |
| 4 | 0 | 0 |
------------------------
2:添加到数组的开头
您将1
添加到数组的开头,获取[1, 0, 12, -10, 1, 0]
。这可以像你期望的那样工作。然而,当你渲染它时,前5个孩子有一个密钥,秘密重新组合,而不是创建新的组件,秘银使用与以前相同的组件。因此,在您的情况下,前五个组件将被重用。
因为你的Counter
每个人只关心attrs
收到的 :
class Counter {
oninit(vnode){
vnode.state.data = vnode.attrs.data
...
...重复使用相同的组件来呈现新号码将无效。
------------------------------------------------
| key | current number | prev number | shows |
------------------------------------------------
| 0 | 1 | 0 | 0 |
| 1 | 0 | 12 | 12 |
| 2 | 12 | -10 | -10 |
| 3 | -10 | 1 | 1 |
| 4 | 1 | 0 | 0 |
| 5 | 0 | new component | 0 |
------------------------------------------------
现有的组件重用它们初始化的数字,只有最后一个使用它在attrs
中收到的数字。