简体   繁体   中英

How to access variable inside React Component? Initialized it outside Component

I'm currently a beginner working on a project in React/Redux. I'm trying to call JSON from an API file, save it as an array of objects, and then pass it into another file to start pulling data out of it. I recently got stuck in one place

Below is my class, which is accessing the JSON data and pulling it out to put into an array. I initialized the array outside of the class, but it's not being written to. I'm not really sure how to 'throw' the array that I need out of my class.

numberendpoint.json (an array of objects)

[
    {
        color: "red",
        value: "#f00"
    },
    {
        color: "green",
        value: "#0f0"
    },
    {
        color: "blue",
        value: "#00f"
    },
    {
        color: "cyan",
        value: "#0ff"
    },
    {
        color: "magenta",
        value: "#f0f"
    },
    {
        color: "yellow",
        value: "#ff0"
    },
    {
        color: "black",
        value: "#000"
    }
]

In index.js

let productJSON = [] //initialize productJSON array here

class Hue extends React.Component {
    constructor() {
        super();
        this.state = {
            elements: [],
            productJSON: []
        };
    }

    componentWillMount() {
        fetch('numberendpoint.json')
        .then(results => {
            return results.json();
        }).then(data => {
            let colorArray = [] //initialize array to receive json data
            for (let i =0; i < data.length; i++) {
                colorArray.push(data[i])
            }
            productJSON = JSON.stringify(productArray) //here is where I try to assign the productJSON array
            let elements = data.map((rainbow) => {
                return (
                    <div key={rainbow.results}>
                        <p>{raindow.color}</p>
                        <p>{rainbow.value}</p>
                    </div>
                )
            })
            this.setState({elements: elements});
            console.log("state", this.state.elements[0]);
        })
    }

    render() {
        return (
            <div>
            <div className="container2">
            {this.state.elements}
        </div>
        </div>
    )}
}

How can I access the JSONproduct array? or alternatively, how do I 'pop' it out of this class so I can use it?

Update: used the solution suggested by Rahamin. Now I have this code below, all contained within the the "Hue" class. But I'm still getting errors.

import React from 'react'

const TIMEOUT = 100

let productJSON;
class Hue extends React.Component {
  constructor() {
    super();
    this.state = {
      products: [],
    };
    this.getColors = this.getColors.bind(this)
  }
  componentDidMount() {
    fetch('http://tech.work.co/shopping-cart/products.json')
      .then(results => {
        return results.json();
      }).then(data => {

    let colorArray = []
    for (let i =0; i < data.length; i++) {
      colorArray.push(data[i])
      }
    console.log("jsonproduct=" + JSON.stringify(productArray))

    productJSON = JSON.stringify(productArray)

   this.setState({productJSON: productJSON});

  });
  }

  render() {
    return (
      <div>
        <div className="container2">
          {this.state.productJSON}
        </div>
      </div>
      )
    }
}


export default {
  getProducts: (cb, timeout) => setTimeout(() => cb(({ productJSON: value})), timeout || TIMEOUT), // here is where I am getting an error -- "value" is undefined. I'm not sure I was meant to put "value" there or something else...very new to React so its conventions are still foreign to me.
  buyProducts: (payload, cb, timeout) => setTimeout(() => cb(), timeout || TIMEOUT)
}
let productJSON = [] //initialize productJSON array here

class Hue extends React.Component {
    constructor() {
        super();
        this.state = {
            elements: [],
            productJSON: []
        };
    }

    componentDidMount() {
        fetch('numberendpoint.json')
        .then(res => {
            this.setState({elements: res.data});
        })
    }

render() {
            if(this.state.elements.length > 0){ //once the data is fetched
              return (
                <div>
                <div className="container2">
                {this.state.elements.map((rainbow) => {
                return (
                    <div key={rainbow.results}>
                        <p>{raindow.color}</p>
                        <p>{rainbow.value}</p>
                    </div>
                )
            })}
            </div>
            </div>
        )
            }
           else{ // initial render
             return null;
           }

}

I don't really understand why you are trying to put array OUTSIDE of a class but I think you need to understand when each event gets called in React.

componentDidMount is an event that gets called when all the components have mounted in the class. So at this stage, render() function has already run. Which means your productJSON is undefined at this stage. What you really wanna do is that make sure your component changes when the state gets updated to something other than undefined .

Try the following code.

let productJSON = [] //initialize productJSON array here

class Hue extends React.Component {
    constructor() {
        super();
        this.state = {
            elements: [],
        };
    }

    componentWillMount() {
        fetch('numberendpoint.json')
        .then(results => {
            return results.json();
        }).then(data => {
            let colorArray = [] //initialize array to receive json data
            for (let i =0; i < data.length; i++) {
                colorArray.push(data[i])
            }
            this.setState({productJSON:colorArray});

            let elements = data.map((rainbow) => {
                return (
                    <div key={rainbow.results}>
                        <p>{raindow.color}</p>
                        <p>{rainbow.value}</p>
                    </div>
                )
            })
            this.setState({elements: elements});
            console.log("state", this.state.elements[0]);
        })
    }

    render() {
        return (
            <div>
            <div className="container2">
            {this.state.productJSON ? 'state not ready' : this.state.productJSON} //this is the important part. It will render this.state.productJSON only when it is a truthy value.
        </div>
        </div>
    )}
}

Given that you do get a valid colorArray from your call, this will work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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