简体   繁体   English

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

[英]React: How to Import and use function to component with setState?

I have some big function methods in my react component and I want to put those functions to separate files, import them with es6 modules system.我的反应组件中有一些大的函数方法,我想将这些函数放在单独的文件中,用es6模块系统导入它们。 The problem is that inside those methods I'm changing the state of the parent component with setState method.问题是,在这些方法中,我正在使用setState方法更改父组件的状态。 What is the best way to use function in separate file, import this function and use with simple setstate method?在单独的文件中使用函数的最佳方法是什么,导入这个函数并使用简单的 setstate 方法?

See the fetchProducts method.请参阅fetchProducts方法。 I want to import this method from separate file我想从单独的文件中导入这个方法

Here is the code:这是代码:

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)

            }
        })
  }

}

Solution without Redux没有 Redux 的解决方案

  1. We export fetchProduct function as a module我们将fetchProduct函数导出为一个模块
  2. Import into our Main component导入到我们的Main组件中
  3. Assign fetchProduct into our componentfetchProduct分配到我们的组件中

We can't use arrow function for fetchProduct.js As stated in YDKJS - "ES6 arrow-functions use lexical scoping for this binding, which means they adopt the this binding (whatever it is) from its enclosing function call."我们不能为fetchProduct.js使用箭头函数正如YDKJS 中所述- “ES6 箭头函数使用词法范围来进行绑定,这意味着它们从其封闭的函数调用中采用 this 绑定(无论它是什么)。”

fetchProducts.js 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();
 }
}

You can simply return the data from your function then set this data in the state of any component :您可以简单地从函数返回数据,然后将此数据设置为任何组件的状态:

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');
    });
};

Then use it in a component :然后在组件中使用它:

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

First you bind your function scope to its owner component scope.首先,您将函数作用域绑定到其所有者组件作用域。

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

Then you export your component instead of its function, which will allow you to access this function as well as the other members of your component.然后导出组件而不是其函数,这将允许您访问此函数以及组件的其他成员。

export default class Main extends React.Component

Then import it at the beginning of your other scripts/components/tests然后在其他脚本/组件/测试的开头导入

import Main from './Main';

And use its function as you see fit并按照您认为合适的方式使用其功能

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

Or you could just export your function, in case that's the only part of your component you want to access.或者您可以只导出您的函数,以防这是您要访问的组件的唯一部分。

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

And then import it in the other scripts然后在其他脚本中导入

import fetchProducts from './Main';

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

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