簡體   English   中英

React:無法在尚未安裝的組件上調用 setState

[英]React: Cant call setState on a component that is not yet mounted

我正在使用 react(MERN stack) 創建一個簡單的待辦事項應用程序。 當我嘗試同時使用 axios 和 setState 調用 get API 時出現上述警告。 我已經通過堆棧溢出的其他線程解決了同樣的問題,但沒有一個真正有用。 我什至試過弄亂“isMounted”變量。 下面是我的代碼...

export default class App extends React.Component{
  _isMounted = false;

  constructor(props){
    super(props);
    this.state = {list:[], itemCounter: 0};
    this.addItem = this.addItem.bind(this);
    this.handleDone = this.handleDone.bind(this);
    this.componentDidMount = this.componentDidMount(this);
  }
  
  componentDidMount(){
    this._isMounted = true;

    axios.get(`http://localhost:8000/todo/api/`)
      .then(res => {
        if(this._isMounted){
          const list = res.data;
          const unDoneList = list.filter(task => task.done === false)
          this.setState({ list: list, itemCounter: unDoneList.length });
      }});
  }

  componentWillUnmount() {
    this._isMounted = false;
  }

  addItem(val) {
    axios.post('http://localhost:8000/todo/api/task/', { data: val })
    .then(res => {
      const itemCounter = this.state.counter + 1;
      const updatedList = this.state.list;
      updatedList.push({ data: val, done: false });
      console.log(res);
      console.log(res.data);
      this.setState({ list: updatedList, itemCounter: itemCounter });
    })
  }
  
  handleDone(item){
    console.log(item._id)
    axios.post(`http://localhost:8000/todo/api/delete/${item._id}`)
    .then(() => console.log("Item Deleted."));

    let updatedList = this.state.list;
    updatedList.forEach(task => {
      if(task.id === item.id ){
        task.done = true;
      }
    });    
    const itemCounter = this.state.itemCounter - 1;
    this.setState({ list: updatedList, itemCounter: itemCounter });
  }

  render(){
    return (
      <div className="App">
      <nav className="panel is-primary light">
        <Title itemCount={this.state.itemCounter}></Title>
        <Add addItem={this.addItem}></Add>
        <Items items={this.state.list} handleDone={this.handleDone}></Items>
      </nav>  
      </div>
    );
  }
}

作為參考,我已將我的整個項目上傳到 GitHub: https://github.com/mohnishm/Todo-App-in-React如何擺脫此警告?

您正在構造函數中調用componentDidMount生命周期方法,您不應該那樣做。

這是問題所在:

this.componentDidMount = this.componentDidMount(this);

如果您在constructor中執行此操作,您會收到該警告,React 會告訴您該組件尚未安裝,但您已經通過手動調用componentDidMount調用了setState

在您的情況下,構造函數尚未完成執行,並且組件沒有機會安裝到 DOM 上。 一旦構造函數被執行,組件就被初始化,然后組件被實際掛載到 DOM 上。

安裝組件后,React 將在適當的上下文中調用您的生命周期方法componentDidMount (因此無需在componentDidMount上調用bind ),然后在那個時間點您應該調用setState來更改組件的 state。

您還可以刪除_isMounted和與該屬性相關的檢查,形成componentDidMountcomponentWillUnmount ,因為它不是必需的。

componentDidMount 是一種生命周期方法,不需要在構造函數中進行初始化。 刪除它以避免警告。

  constructor(props){
    super(props);
    this.state = {list:[], itemCounter: 0};
    this.addItem = this.addItem.bind(this);
    this.handleDone = this.handleDone.bind(this);
    this.componentDidMount = this.componentDidMount(this); // remove this, componentDidMount is a lifecycle method.
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM