简体   繁体   English

如何在渲染内的react js中传递数组

[英]How to pass array in react js inside render

I'm developing a IPFS-Ethereum app using React JS where I will upload a XML file and parse it.我正在使用 React JS 开发一个 IPFS-Ethereum 应用程序,我将在其中上传一个 XML 文件并对其进行解析。 I got a problem displaying parsed data as an array in the table.我在将解析的数据显示为表中的数组时遇到问题。 It is showing only last element in the array.它只显示数组中的最后一个元素。

This is the code used for parsing, in console it is showing the two data in the console which is parsed. But in Table it is showing only the last element. I tried using this this.liItem[i]/this.liItem[0] but it is throwing undefined error.

var request = new Request(`https://gateway.ipfs.io/ipfs/${this.state.ipfsHash}`);
fetch(request).then((results) => {
  // results returns XML. lets cast this to a string, then create
  // a new DOM object out of it!
  results
    .text()
    .then((str) => {
      this.state.responseDoc = new DOMParser().parseFromString(str, 'application/xml');
      console.log(this.state.responseDoc);

      this.state.listItem = this.state.responseDoc.getElementsByTagName('Name');
      // console.log(listItem);
      for (this.i = 0; this.i < this.state.listItem.length; this.i++) {
        this.liItem = this.state.responseDoc.getElementsByTagName('Name')[this.i].textContent;
        this.setState({
          liItem: this.state.liItem
        });
        console.log(this.liItem);
      }
    })

This is the line {this.liItem} used in in the table to display array data.这是表中用于显示数组数据的行 {this.liItem}。 ( picture link ) 图片链接

This is my App.js file.这是我的 App.js 文件。

import {Table, Grid, Button, Form } from 'react-bootstrap';从'react-bootstrap' 导入 {Table, Grid, Button, Form }; import React, { Component } from 'react'; import React, { Component } from 'react'; import './App.css';导入'./App.css'; import web3 from './web3';从 './web3' 导入 web3; import ipfs from './ipfs';从'./ipfs'导入ipfs; import storehash from './storehash';从 './storehash' 导入 storehash;

class App extends Component {
  state = {
    ipfsHash:null,
    buffer:'',
    ethAddress:'',
    blockNumber:'',
    transactionHash:'',
    gasUsed:'',
    txReceipt: '',
    responseDoc:'',
    listItem:'',
    i:'',
    liItem:[]
  };


  captureFile =(event) => {
    event.stopPropagation()
    event.preventDefault()
    const file = event.target.files[0]
    let reader = new window.FileReader()
    reader.readAsArrayBuffer(file)
    reader.onloadend = () => this.convertToBuffer(reader)    
  };

  convertToBuffer = async(reader) => {
    //file is converted to a buffer to prepare for uploading to IPFS
    const buffer = await Buffer.from(reader.result);
    //set this buffer -using es6 syntax
    this.setState({buffer});
  };

  onClick = async () => {
  try{
      this.setState({blockNumber:"waiting.."});
      this.setState({gasUsed:"waiting..."});

      // get Transaction Receipt in console on click
      // See: https://web3js.readthedocs.io/en/1.0/web3- eth.html#gettransactionreceipt
      await web3.eth.getTransactionReceipt(this.state.transactionHash, (err, txReceipt)=>{
      console.log(err,txReceipt);
        this.setState({txReceipt});
      }); //await for getTransactionReceipt

      await this.setState({blockNumber: this.state.txReceipt.blockNumber});
      await this.setState({gasUsed: this.state.txReceipt.gasUsed});    
    } //try
    catch(error){
    console.log(error);
    } //catch


    var request = new Request(`https://gateway.ipfs.io/ipfs/${this.state.ipfsHash}`);
    fetch(request).then((results) => {
      // results returns XML. lets cast this to a string, then create
      // a new DOM object out of it!
      results
      .text()
      .then(( str ) => {
        this.state.responseDoc = new DOMParser().parseFromString(str, 'application/xml');
        console.log(this.state.responseDoc);

        this.state.listItem  = this.state.responseDoc.getElementsByTagName('Name');
                // console.log(listItem);
        for (this.i=0; this.i<this.state.listItem.length; this.i++){
          this.liItem = this.state.responseDoc.getElementsByTagName('Name')[this.i].textContent;
          this.setState({liItem: this.state.liItem});
          console.log(this.liItem);
        }
      })
    });
  } //onClick

  onSubmit = async (event) => {
    event.preventDefault();

    //bring in user's metamask account address
    const accounts = await web3.eth.getAccounts();

    console.log('Sending from Metamask account: ' + accounts[0]);

    //obtain contract address from storehash.js
    const ethAddress= await storehash.options.address;
    this.setState({ethAddress});

    //save document to IPFS,return its hash#, and set hash# to state
    //https://github.com/ipfs/interface-ipfs-core/blob/master/SPEC/FILES.md#add 
    await ipfs.add(this.state.buffer, (err, ipfsHash) => {
      console.log(err,ipfsHash);
      //setState by setting ipfsHash to ipfsHash[0].hash 
      this.setState({ ipfsHash:ipfsHash[0].hash });


      // call Ethereum contract method "sendHash" and .send IPFS hash to etheruem contract 
      //return the transaction hash from the ethereum contract
      //see, this https://web3js.readthedocs.io/en/1.0/web3-eth-contract.html#methods-mymethod-send

      storehash.methods.sendHash(this.state.ipfsHash).send({
          from: accounts[0] 
        }, (error, transactionHash) => {
          console.log(transactionHash);
          this.setState({transactionHash});
        }

      ); //storehash 
    }) //await ipfs.add
  }; //onSubmit 


  render() {

    return (
      <div className="App">
        <header className="App-header">
          <h1>
            {" "}
            Ethereum and InterPlanetary File System(IPFS) with Create React App
          </h1>
        </header>
        <hr />

        <Grid>
          <h3> Choose file to send to IPFS </h3>
          <Form onSubmit={this.onSubmit}>
            <input type="file" onChange={this.captureFile} />
            <Button bsStyle="primary" type="submit">
              Send it
            </Button>
          </Form>
          <br />

          <img
            src={`https://ipfs.io/ipfs/${this.state.ipfsHash}`}
            alt=""
            style={{ height: 200 }}
          />

          <hr />
          <Button onClick={this.onClick}> Get Transaction Receipt </Button>
          <Table bordered responsive>
            <thead>
              <tr>
                <th>Tx Receipt Category</th>
                <th>Values</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td>IPFS Hash # stored on Eth Contract</td>
                <td>{this.state.ipfsHash}</td>
              </tr>
              <tr>
                <td>Ethereum Contract Address</td>
                <td>{this.state.ethAddress}</td>
              </tr>
              <tr>
                <td>Tx Hash # </td>
                <td>{this.state.transactionHash}</td>
              </tr>
              <tr>
                <td>Block Number # </td>
                <td>{this.state.blockNumber}</td>
              </tr>
              <tr>
                <td>Gas Used</td>
                <td>{this.state.gasUsed}</td>
              </tr>
              <tr>
                <td>XML</td>
                <td>{this.liItem}</td>
              </tr>
            </tbody>
          </Table>
        </Grid>
      </div>
    );
    //render
  }
}

export default App;

I hope you people will understand my question and give me a solution.我希望你们能理解我的问题并给我一个解决方案。 Thank You谢谢你

Try this:尝试这个:

<tr>
    <td>XML</td>
    <td>{this.liItem.map((value, index) => {
        <p key={index}>{value}</p>
    })}</td>
</tr>

with that you should get all the entries in a seperated line (cause p is w=100%)有了它,您应该将所有条目放在单独的行中(因为 p 是 w=100%)

There was little change in the code and this worked for me.代码几乎没有变化,这对我有用。

var request = new Request(`https://gateway.ipfs.io/ipfs/${this.state.ipfsHash}`);
  fetch(request).then((results) => {
    // results returns XML. lets cast this to a string, then create
    // a new DOM object out of it!
    //Array Declaration
    var values=[];
    results
      .text()
      .then(( str ) => {
        this.state.responseDoc = new DOMParser().parseFromString(str, 'application/xml');
        console.log(this.state.responseDoc);

        this.state.listItem  = this.state.responseDoc.getElementsByTagName('Name');
        for (this.i=0; this.i<this.state.listItem.length; this.i++){
        //Pushing values into the array
        values.push(this.state.responseDoc.getElementsByTagName('Name')[this.i].textContent);
        console.log(values);
         }
        this.setState({liItem: values});
      })
    });

 And down in the render I used this for displaying
 <tr>
 <td>
 XML
 </td>
 <td>
 {this.state.liItem.map(x => {return x})}
 </td>
 </tr>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM