簡體   English   中英

.push()在構造函數中不起作用?

[英].push() does not work in the constructor?

我有這樣一個數組:

product = [
    {
        name: " size one",
        price: 1
      },
      {
        name: "size two",
        price: 2
      },
      ,
      {
        name: "size three",
        price: 3
      }
    ];

我以前曾這樣分隔奇偶數組索引:

for (let i=0; i< product.length; i++ ) {
      if (i % 2 === 0 ){
        evenArray.push(product[i])
      } else {
        oddArray.push(product[i])
      }
    };

但我想將其移至構造函數而不是渲染。 我在componenetDidMount()這樣寫:

  for (let i=0; i< this.state.product.length; i++ ) {
      if (i % 2 === 0 ){
        this.setState({
        evenArray: [...this.state.evenArray, this.state.product[i]]
      });
      } else {
        this.setState({
        oddArray: [...this.state.oddArray, this.state.product[i]]
      });
      }
    };

但這是行不通的。 我對不能直接更改狀態而只能更新狀態的想法很熟悉,這就是為什么不能使用.push()但上面的方法為什么不起作用的原因?

-----實碼編輯-----

componentDidMount() {
  const oauth = OAuth({
    consumer: {
      key: 'XXXXXXXXX',
      secret: 'XXXXXXXXXXX',
    },
    signature_method: 'HMAC-SHA1',
    hash_function(base_string, key) {
      return crypto.createHmac('sha1', key).update(base_string).digest('base64');
    }
  });

  const request_data1 = {
    url: 'http://localhost:8888/wp-json/wc/v2/products/28/variations?per_page=15',
    method: 'GET',
  };

  const request_data2 = {
    url: 'http://localhost:8888/wp-json/wc/v2/products/28/',
    method: 'GET',
  };

  fetch(request_data1.url, {
    method: request_data1.method,
    headers: oauth.toHeader(oauth.authorize(request_data1))
  })
    .then(response => response.json())
    .then(response => {
      this.setState({
         products1: response.reverse()
      })
   })

   fetch(request_data2.url, {
     method: request_data2.method,
     headers: oauth.toHeader(oauth.authorize(request_data2))
   })
     .then(response => response.json())
     .then(response => {
       this.setState({
          products2: response
       })
    })

    const evenArray = [];
    const oddArray = [];
    for (let i = 0; i < this.state.products1.length; i++) {
      if (i % 2 === 0) {
        evenArray.push( this.state.products1[i] );
      } else {
        oddArray.push(this.state.products1[i]);
      }
    };

    this.setState( prevState => ({
        evenArray: [ ...prevState.evenArray, ...evenArray ],
        oddArray: [...prevState.oddArray, ...oddArray],
    }));

}

由於無法在設置狀態之前完成for循環,因此無法成功設置狀態。 由於這個原因,我不喜歡for循環,我們通常不使用它們,但是您可以按照以下方式進行:

 class App extends React.Component { state = { product: [ { name: " size one", price: 1 }, { name: "size two", price: 2 }, { name: "size three", price: 3, } ], evenArray: [], oddArray: [], } componentDidMount() { const evenArray = []; const oddArray = []; for (let i = 0; i < this.state.product.length; i++) { if (i % 2 === 0) { evenArray.push( this.state.product[i] ); } else { oddArray.push(this.state.product[i]); } }; this.setState( prevState => ({ evenArray: [ ...prevState.evenArray, ...evenArray ], oddArray: [...prevState.oddArray, ...oddArray], })); } render() { console.log( this.state ); return <div> Evens: {JSON.stringify(this.state.evenArray)} Odds: {JSON.stringify(this.state.oddArray)} </div>; } } ReactDOM.render(<App />, document.getElementById("root")); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id="root"></div> 

評論后更新

由於您正在獲取數據,因此在再次完成數據之前,您嘗試設置狀態。 我試圖模仿這種情況。 這只是許多解決方案的一種。

 const product1 = [ { name: " size one", price: 1 }, { name: "size two", price: 2 }, { name: "size three", price: 3, } ]; const fakeRequest = () => new Promise( resolve => setTimeout( () => resolve( product1 ), 2000 ) ); class App extends React.Component { state = { product1: [], evenArray: [], oddArray: [], } componentDidMount() { fakeRequest() .then( product1 => { const evenArray = product1.filter((el, i) => i % 2 === 0); const oddArray = product1.filter((el, i) => i % 2 !== 0); this.setState( prevState => ( { product1: [ ...prevState.product1, ...product1 ], evenArray: [...prevState.evenArray, ...evenArray ], oddArray: [...prevState.oddArray, ...oddArray], } )) }) } render() { console.log(this.state); return <div> { !this.state.product1.length && <p>Waiting for 2 seconds...</p> } Evens: {JSON.stringify(this.state.evenArray)} Odds: {JSON.stringify(this.state.oddArray)} </div>; } } ReactDOM.render(<App />, document.getElementById("root")); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id="root"></div> 

第二次更新

我使用了fakeRequest來模仿您的情況,請不要使用它。 您的代碼可能如下所示:

fetch(request_data1.url, {
    method: request_data1.method,
    headers: oauth.toHeader(oauth.authorize(request_data1))
  })
    .then(response => response.json())
    .then(response => {
         const products1 = response.reverse();
         const evenArray = products1.filter((el, i) => i % 2 === 0);
         const oddArray = products1.filter((el, i) => i % 2 !== 0);
         this.setState( prevState => ( {
              product1: [ ...prevState.products1, ...product1 ],
              evenArray: [...prevState.evenArray, ...evenArray ],
              oddArray: [...prevState.oddArray, ...oddArray],
         } ))
})

您不應在構造函數中調用this.setState 而是將其設置為初始狀態:

constructor(props) {
  super(props);
  this.state = {
    evenArray: evenArray, 
    oddArray: oddArray,
  };
}

暫無
暫無

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

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