我有一个这样的数组:
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],
}));
}
答案 0 :(得分:2)
由于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],
} ))
})
答案 1 :(得分:0)
您不应在构造函数中调用this.setState
。而是将其设置为初始状态:
constructor(props) {
super(props);
this.state = {
evenArray: evenArray,
oddArray: oddArray,
};
}