简体   繁体   English

尽管使用了 setState(),但在 state 更改后反应组件未重新渲染

[英]React component not rerendering after state change despite using setState()

I tried to fetch data from an embedded sqlite db and displayed it in list format.我试图从嵌入式 sqlite 数据库中获取数据并以列表格式显示。 The fetchData() function is working, with correct returned result. fetchData() function 正在工作,并返回正确的结果。 However, when I used setState() to update the state, react did not re-render.但是,当我使用 setState() 更新 state 时,react 没有重新渲染。 Next I tried to setState() with array ['a','b','c'] at componentDidMount().接下来,我尝试在 componentDidMount() 中使用数组 ['a','b','c'] 设置状态()。 React did re-render and showed a, b, c. React 确实重新渲染并显示了 a、b、c。

import React from 'react';
import sqlite3 from 'sqlite3';


type MyProps = {  };
type MyState = { data: Array<string> };

class App extends React.Component<MyProps, MyState>{
  constructor(props) {
    super(props);
    this.state = { data: [] };
    
  }

  async fetchData(){
    var db = new sqlite3.Database({$DB_PATH});
    var res: string[] = [];
    await db.each('select * from table', [], (err, row) => { //selecting 10 rows from table
      if (err) {
        throw err;
      }
        res.push(row.name);
    });
    db.close();
    console.log(this.state.data) //array length = 0
    this.setState({data: res})
    console.log(this.state.data) //array length = 10
  }

   async componentDidMount() {
      await this.fetchData();   
  }

  render() {
  return (
     <div>
        <ul>
          {this.state.data.map(el => (
            <li>
              {el}
            </li>
          ))}
        </ul>
    </div>
  );
  }
}
export default App;

Because of db.each won't return a Promise so that you cannot reach result by 'await' statement.由于db.each不会返回Promise ,因此您无法通过“等待”语句获得结果。 Refer to the APIs , you'll need to this:请参阅APIs ,您需要这样做:

each(sql: string, params: any, callback?: (this: Statement, err: Error | null, row: any) => void, complete?: (err: Error | null, count: number) => void): this;

so, you should access the result in the complete callback, code like so:因此,您应该在complete的回调中访问结果,代码如下:

async fetchData() {
  const db = new sqlite3.Database({ $DB_PATH });
  const res: string[] = [];
  await db.each('select * from table', [], (err, row) => { // selecting 10 rows from table
    if (err) {
      throw err;
    }
    res.push(row.name);
  }, () => {
    console.log(this.state.data) // array length = 0
    this.setState({ data: res })
    console.log(this.state.data) // array length = 10
    db.close();
  });
}

Hope it will be helpful.希望它会有所帮助。


Besides, you can also have a try with Statement#all([param, ...], [callback]) function which is a better than each .此外,您还可以尝试Statement#all([param, ...], [callback]) function ,它比each更好。

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

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