reactJS和动态渲染以及可变填充

时间:2018-08-25 21:06:03

标签: reactjs

我想在我的render()中动态生成输出,但是遇到了一种非常奇怪的情况。我有一个过程,可以使用fetch()从数据库中检索一些数据。取回数据后,我将确定数据记录的数量,然后执行for循环以使用返回的数据填充数组。在for循环之前,我有一个console.log()来显示我的数据接收数组的内容,而在填充接收数组时,我还有另一个console.log()。由于某种原因,当我填充数组的特定实例时,该数组的所有实例似乎都在变化。这是我的全部代码:

import React from 'react';
import '../styles/app.css';


class testpage extends React.Component {


constructor(props) {
    super(props);
    this.state = {
        productArray: []
    };

}


componentWillMount() {

    var tempData = '';
    var numberOfRecords = 0;

    let url = "http://wmjwwebapi-dev.us-west-2.elasticbeanstalk.com/api/getdata";
    const options = { method: 'GET' };

    fetch(url, options)
    .then(function(response) {
        return response.json();
    })
    .then(function(myJson) {
        if (myJson == undefined) 
        {
            console.log("fetch failed");
        } 
        else 
        {
            //inspect the data that the WebAPI returned 
            var return_code = myJson[0].return_code;
            if (return_code == "Default Return code"){
                tempData = '';
                numberOfRecords = -2;
            } else {
                tempData = JSON.parse(myJson[0].return_string)
                numberOfRecords = tempData.barcode.length;

                var counter = 0;
                var productArray = new Array;
                var product = {
                    barcode: '',
                    name: '',
                    description: '',
                    image: '',
                    price: ''
                }


                for (counter=0;counter<numberOfRecords;counter++) {
                    product.barcode = tempData.barcode[counter];
                    product.name = tempData.name[counter];
                    productArray[counter] = product;
                }                  
            }
        }
    }); 
  }

render() {
    <div>
        <div>
            {this.state.productArray[0].barcode}
        </div>
    </div>
}

}

export default testpage;

这是当循环计数器= 0时在console.log()中看到的图像: enter image description here

注意条形码值5000159459228吗?该值被推入productArray [0] .barcode。这就是我所期望的。

这是当循环计数器= 1时在console.log()中看到的图像: enter image description here 此处,读取的记录的条形码为5000159459230。此值应输入productArray 1。barcode中,该图像将显示该值。但是,该图像还显示productArray [0] .barcode的值已从5000159459228(第一条记录的值)更改为5000159459230(第二条记录的值)。

这是从第三次到循环的图像: enter image description here

同样,重新创建一条条形码= 5000159459231的新记录。该值似乎已推送到productArray 2。barcode中,但productArray [0] .barcode和productArray 1。barcode现在已更改。

那怎么可能?

最终,目标是动态呈现检索到的数据。

在此先感谢您的帮助。

3 个答案:

答案 0 :(得分:3)

控制台输出通常可用于基元,但不能用于对象。控制台实现特定于执行脚本(浏览器)的环境。

正在输出的是对象引用,而不是对象快照。更改对象后,其在控制台中的表示形式也可以更改。

请注意,在Chrome控制台中,该数组最初记录为[]个空数组,而下一个日志条目是[...]个非空数组。

要输出不会追溯更改的对象快照,请使用console.log(JSON.stringify(array))或其他序列化的原始值。

答案 1 :(得分:0)

我建议使用chrome devtools进行调试,并在填充数组的位置添加断点。
您也可以在代码中的任何位置添加debugger,然后将提示devtools。 对于更改,我第二个@estus反映了您曾经使用过Console的对象更新。

答案 2 :(得分:0)

聊天后,在Code Review的帮助下了解了数据形状,这是我们可以做到的:

const json = [{
  return_string: {
    "barcode": ["5000159459228", "5000159459229", "5000159459230"],
    "scan_date": ["20180825173416", "20180825173416", "20180825173416"],
    "name": ["Twix Twin Chocolate Bars - 50g - Pack of 6 (50g x 6 Bars) (1.76 oz  x  6)", "Twix Twin Chocolate Bars - 50g - Pack of 6 (50g x 6 Bars) (1.76 oz  x  6)", "Twix Twin Chocolate Bars - 50g - Pack of 6 (50g x 6 Bars) (1.76 oz  x  6)"],
    "description": ["Twix Twin Chocolate Bars - 50g - Pack of 6 (50g x 6 Bars) (1.76 oz  x  6)", "Twix Twin Chocolate Bars - 50g - Pack of 6 (50g x 6 Bars) (1.76 oz  x  6)", "Twix Twin Chocolate Bars - 50g - Pack of 6 (50g x 6 Bars) (1.76 oz  x  6)"],
    "image": ["http://thumbs2.ebaystatic.com/m/mv0sDuMCXy5TgjQFYC0CJAQ/140.jpg", "http://thumbs2.ebaystatic.com/m/mv0sDuMCXy5TgjQFYC0CJAQ/140.jpg", "http://thumbs2.ebaystatic.com/m/mv0sDuMCXy5TgjQFYC0CJAQ/140.jpg"],
    "price": ["1", "2", "3"]
  }
}];

const fakeRequest = () => new Promise( resolve =>
  setTimeout( () => resolve( json ) )
);

class App extends React.Component {
  state = {
    data: "",
  }

  componentDidMount() {
    fakeRequest()
      .then( res => {
        this.setState({
          data: res[0].return_string,
        })
      })
  }

  renderData = () => {
    const { data } = this.state;
    const values = Object.values(data);
    const keys = Object.keys(data);
    
    const transposed = values[0].map((col, i) =>
      values.map(row => row[i]));
    
    const items = transposed.map(itemArr =>
      keys.reduce((acc, key, i) => (
        { ...acc, [key]: itemArr[i] }), {})
    );
    
    return items.map( item => (
      <div style={{ border: "1px solid black", marginBottom: "3px" }}>
        <p>Barcode: {item.barcode}</p>
        <p>Scan date: {item.scan_date}</p>
        <p>Name: {item.name}</p>
        <p>Description: {item.description}</p>
        <p>Image: {item.image}</p>
        <p>Price: {item.price}</p>
      </div>
    ) )
  }

  render() {
    return <div>{this.state.data && this.renderData()}</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>

困难的部分是将数据正确地转换为对象数组。因为,这种数据形状对我来说有点奇怪:)包含数组属性的对象。这些数组元素按顺序匹配。 ew:)