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