React:如何使用setState导入和使用函数到组件?

时间:2017-09-23 11:11:57

标签: javascript reactjs es6-modules

我的react组件中有一些很大的函数方法,我想把这些函数放到单独的文件中,用es6模块系统导入它们。 问题是在那些方法中我用setState方法改变父组件的状态。 在单独的文件中使用函数的最佳方法是什么,导入此函数并使用简单的setstate方法?

请参阅fetchProducts方法。我想从单独的文件中导入此方法

以下是代码:

import React from 'react'
import Header from '../components/Header'

class Main extends React.Component { 
 constructor(props) {
    super(props)
    this.state = {
        firstDetected: false,
        detected: false,
        products: [],
        selectedProduct: null,
        premiumImage: null,
        productImages: [],
        productPrice: null,
        dataFromServer: null,
        default_gender: null,
        bgImage: null,
        productsExtension: null,
        mediaCdn: null,
        fade: false,
        hello: false,
        helloEnd: false,
        collection: false,
        collectionEnd: false,
        capturedImage: null,
        imageReady: false,
        gender: null,
        waitForEnding: true

    }
 }

 componentWillMount() {
    this.fetchProducts(1)
 }

 fetchProducts = (init) => {
    auth.fetch(`${baseUrlTest}/products/get-user-products?init=${init}`)
        .then(res => {

            if (Object.keys(res).length) {
                console.log(res)
                const productsExtension = res['products.extension']
                const mediaCdn = res['media.cdn']
                const randomProduct = randomize(res['products'])

                this.setState({
                    dataFromServer: res,
                    products: res.products,
                    selectedProduct: randomProduct,
                    default_gender: res.default_gender,
                    bgImage: res['background.image'],
                    productsExtension: productsExtension,
                    mediaCdn: mediaCdn,
                    gender: res.default_gender,
                    premiumImage: mediaCdn + randomProduct.image + '.' + productsExtension.find(k => k === 'jpg'),
                    productPrice: randomProduct.price,
                    productImages: res.products.filter((prod) => {
                        return prod.gender === res.default_gender
                    }).map((prod) => {
                        return prod
                    })

                })

                console.log(res.products)

            }
        })
  }

}

3 个答案:

答案 0 :(得分:1)

没有Redux的解决方案

  1. 我们将fetchProduct函数导出为模块
  2. 导入我们的Main组件
  3. fetchProduct分配到我们的组件
  4.   

    我们无法对fetchProduct.js使用箭头功能,如YDKJS中所述 -    “ES6 arrow-functions使用词法作用域进行绑定,这意味着它们从其封闭的函数调用中采用了这种绑定(无论它是什么)。”

    <强> fetchProducts.js

    // Export the function as a module
    export default function fetchProducts(init) {
        auth.fetch(`${baseUrlTest}/products/get-user-products?init=${init}`)
            .then(res => {
    
                if (Object.keys(res).length) {
                    console.log(res)
                    const productsExtension = res['products.extension']
                    const mediaCdn = res['media.cdn']
                    const randomProduct = randomize(res['products'])
    
                    this.setState({
                        dataFromServer: res,
                        products: res.products,
                        selectedProduct: randomProduct,
                        default_gender: res.default_gender,
                        bgImage: res['background.image'],
                        productsExtension: productsExtension,
                        mediaCdn: mediaCdn,
                        gender: res.default_gender,
                        premiumImage: mediaCdn + randomProduct.image + '.' + productsExtension.find(k => k === 'jpg'),
                        productPrice: randomProduct.price,
                        productImages: res.products.filter((prod) => {
                            return prod.gender === res.default_gender
                        }).map((prod) => {
                            return prod
                        })
    
                    })
    
                    console.log(res.products)
    
                }
            })
      }
    

    <强> Main.js

    import React from 'react'
    import Header from '../components/Header'
    // Import the exported function from fetchProduct.js
    import fetchProducts from "../middleware/fetchProduct.js"
    
    class Main extends React.Component { 
     constructor(props) {
        super(props)
        this.state = {
            firstDetected: false,
            detected: false,
            products: [],
            selectedProduct: null,
            premiumImage: null,
            productImages: [],
            productPrice: null,
            dataFromServer: null,
            default_gender: null,
            bgImage: null,
            productsExtension: null,
            mediaCdn: null,
            fade: false,
            hello: false,
            helloEnd: false,
            collection: false,
            collectionEnd: false,
            capturedImage: null,
            imageReady: false,
            gender: null,
            waitForEnding: true
        }
     }
     componentWillMount() {
        // Assign fetchProducts into your Component
        this.fetchProducts = fetchProducts.bind(this);
        // Call fetchProduct() inside your Component
        this.fetchProducts();
     }
    }
    

答案 1 :(得分:0)

您只需从函数返回数据,然后将此数据设置为任何组件的状态:

fetchProducts = init => {
  return auth
    .fetch(`${baseUrlTest}/products/get-user-products?init=${init}`)
    .then(res => {
      if (Object.keys(res).length) {
        console.log(res);
        const productsExtension = res['products.extension'];
        const mediaCdn = res['media.cdn'];
        const randomProduct = randomize(res['products']);

        return {
          dataFromServer: res,
          products: res.products,
          selectedProduct: randomProduct,
          default_gender: res.default_gender,
          bgImage: res['background.image'],
          productsExtension: productsExtension,
          mediaCdn: mediaCdn,
          gender: res.default_gender,
          premiumImage:
            mediaCdn +
            randomProduct.image +
            '.' +
            productsExtension.find(k => k === 'jpg'),
          productPrice: randomProduct.price,
          productImages: res.products
            .filter(prod => {
              return prod.gender === res.default_gender;
            })
            .map(prod => {
              return prod;
            })
        };
      }
      throw new Error('res has no data');
    });
};

然后在组件中使用它:

componentDidMount() {
    fetchProducts('initVar').then(res => this.setState(res)).catch(err => console.log(err));
}

答案 2 :(得分:0)

首先,您将功能范围绑定到其所有者组件范围。

class Main extends React.Component {
    constructor(props) {
        // {...}
        this.fetchProducts = this.fetchProducts.bind(this);
    }
}

然后导出组件而不是其功能,这将使您可以访问此功能以及组件的其他成员。

export default class Main extends React.Component

然后将其导入其他脚本/组件/测试的开头

import Main from './Main';

并根据需要使用其功能

let state = {};
Main.fetchProducts(state);

或者,如果这是您要访问的组件的唯一部分,则可以只导出函数。

class Main extends React.Component {
    // {...}
    export fetchProducts {
        // {...}
    }
}

然后将其导入其他脚本中

import fetchProducts from './Main';