繁体   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