简体   繁体   English

反应setState不适用于流数据吗?

[英]react setState doesn't work with stream data?

I'm using PouchDB to sync my remote db with my localdb, below code is placed in componentDidMount 我正在使用PouchDB将远程数据库与localdb同步,下面的代码放置在componentDidMount中

const that = this
var localDB = new PouchDB('localdb')
var remoteDB = new PouchDB('http://192.168.1.106:5984/remotedb')

localDB.sync(remoteDB, {
    live: true,
    retry: true
}).on('change', function (change) {
    console.log('test')
    that.setState({
      items: [this.state.items, ...change.change.docs]
    })
})

I have no clue why it doesn't do anything at all 我不知道为什么它什么都不做

There are three problems there: 那里存在三个问题:

  1. You've used this instead of that in the change callback. 您已经在change回调中使用了this而不是that It's almost certainly doing something: Writing an error the console. 几乎可以肯定,它正在做一些事情:在控制台中写一个错误。 (Rather than the that pattern, just use an arrow function so you can use this.) (而不是that模式,只需使用箭头功能,就可以使用它。)

  2. You're breaking one of the fundamental rules of React: If you'e setting state based on existing state (which you are, you're using this.state.items as part of the new state), you must use the callback version of setState ( more here ). 您违反了React的基本规则之一:如果要基于现有状态设置状态(您正在使用this.state.items作为新状态的一部分),则必须使用回调版本setState的( 这里有更多 )。

  3. You almost certainly wanted to spread this.state.items rather than including that array as your first element in the new array. 您几乎肯定要散布this.state.items而不是将该数组作为新数组中的第一个元素。 (I don't know whether you also wanted to spread change.change.docs .) (我不知道您是否还想传播change.change.docs 。)

Fixing all three: 修复所有三个:

localDB.sync(remoteDB, {
    live: true,
    retry: true
}).on('change', change => {
    this.setState(({items}) => ({items: [...items, /*...*/change.change.docs]}));
})

(The /*...*/ is: Use ... there if you really want to spread change.change.docs , or remove it if you don't.) /*...*/是:如果您真的想传播change.change.docs ,请使用... change.change.docs ,请删除它。)

That uses an arrow function so you don't need the that variable, and uses the callback version of setState with destructuring in the parameter list to grab the items state member and create a new items member with change.change.docs appended. 它使用箭头函数,因此您不需要that变量,并使用setState的回调版本以及在参数列表中进行销毁的功能来获取items状态成员,并创建一个附加了change.change.docs的新items成员。

We could use destructuring in the parameter list of the change callback as well: 我们也可以在change回调的参数列表中使用解构:

localDB.sync(remoteDB, {
    live: true,
    retry: true
}).on('change', ({change: {docs}}) => {
    this.setState(({items}) => ({items: [...items, /*...*/docs]}));
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM