简体   繁体   English

状态未定义的变量 React.js

[英]Variable in state undefined React.js

I'm trying to store product from an API in the state of my React component and then map them in the render function of the component but somehow this.state.products is undefined .我试图将来自 API 的产品存储在我的 React 组件的状态中,然后将它们映射到组件的渲染函数中,但不知何故this.state.productsundefined

This is my components code (CategoryProducts.js):这是我的组件代码(CategoryProducts.js):

class CategoryProducts extends Component{
    constructor(props){
        super(props); 
        this.state = {}
        this.products = new Products(); 
    }

    async componentWillMount(){
        await this.products.getProductsInCategory(this.props.name).then(
            (val) => {
                this.setState({products: val}); 
            }
        )
    }

    render(){
        return(
            <Container className='content-container'> 
                <Row>
                    <Col md={12}>
                        <h4 className="mb-0">{this.props.name}</h4>
                        <hr></hr>
                    </Col>
                </Row>
                <Row>
                    <Col md={2}>
                        Some space for possible filters in the future 
                    </Col>
                    <Col md={10}>
                        {this.state.products.map(function(item, i){
                            console.log(i); 
                        })}
                    </Col>
                </Row>
            </Container>
        );
    }
}

The call to the API is async this is the corresponding code:对 API 的调用是异步的,这是相应的代码:

Products.js:产品.js:

export class Products extends API {

    getProducts() {
        return this.get('/products')
    }
    getCategories(){
        return this.get('/products/categories'); 
    }
    getProductsInCategory(_category){
        return this.get('/products/withcategory/' + _category); 
    }
}

And this method inside the API class: API类中的这个方法:

async get(_endpoint) {
        let response = await fetch(this.API_url + _endpoint);
        return response.json();
    }

I hope someone can help me out with this issue我希望有人能帮我解决这个问题

The first time render() is called, the API call might not be ready yet.第一次调用 render() 时,API 调用可能还没有准备好。 You need to take this into account in your render() function.您需要在 render() 函数中考虑到这一点。

The easiest way is something like:最简单的方法是这样的:

{this.state.products && this.state.products.map(function(item, i){
                        console.log(i); 
                    })}

This will only do the mapping when this.state.products has some value.这只会在this.state.products有一些值时进行映射。

You could also show some loading component while the products are being loaded by adding something like this in your render() function.您还可以在加载产品时通过在 render() 函数中添加类似内容来显示一些加载组件。

{ !this.state.products && <SomeLoadingComponent /> }

You are turning the componentWillMount into a promise so that part won't be executed as such by RN:您正在将 componentWillMount 转换为承诺,以便 RN 不会执行该部分:

 async componentWillMount(){
        await this.products.getProductsInCategory(this.props.name).then(
            (val) => {
                this.setState({products: val}); 
            }
        )
    }

Try this:试试这个:

constructor(props){
        super(props); 
        this.state = {
            products: [] //Or whatever suits you best
         }
        this.products = new Products(); 
    }

 componentWillMount(){
        this.products.getProductsInCategory(this.props.name).then(
            (val) => {
                this.setState({products: val}); 
            }
        )
    }

componentWillMount() is invoked immediately before mounting occurs. componentWillMount()在挂载发生前立即被调用。 It is called before render() , therefore calling setState() synchronously in this method will not trigger an extra rendering它在render()之前调用,因此在该方法中同步调用setState()不会触发额外的渲染

You should avoid to place a API call in componentWillMount life cycle method.您应该避免在componentWillMount生命周期方法中放置 API 调用。

Instead use,componentDidMount而是使用componentDidMount

async componentDidMount(){
        await this.products.getProductsInCategory(this.props.name).then(
            (val) => {
                this.setState({products: val}); 
            }
        )
    }

Define variable in定义变量

class CategoryProducts extends Component{
constructor(props){
    super(props); 
    this.state = {products : '';}
     
}
enter code here

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

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