[英].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.