反应组件中的位置以添加简单的数学函数

时间:2019-01-14 08:00:08

标签: javascript reactjs

我有一个简单的react组件,我想向其中添加一个使用属性值的名为doMath的简单数学函数。

class MyClass extends Component {
    constructor( props ) {
        super( ...arguments );
    }

    render() {
        const { attributes } = this.props; /* attributes passed from parent component */
        const { width, height } = attributes;

        return (
           /* render something using the width and height values */
        )
    }
}

我可以通过以下方式添加doMath函数...

在课程内:

class MyClass extends Component {
    constructor( props ) {
        super( ...arguments );
    }

    doMath() {
       const { width, height } = this.props.attributes;
       const result = 100 / (width / height);
       return result;
    }

    render() {
        const { attributes } = this.props; /* attributes passed from parent component */
        const { width, height } = attributes;

        return (
           doMath();
        )
    }
}

在类之外作为const:

const doMath = (width, height) {
  const result = 100 / (width / height);
  return result;
}

class MyClass extends Component {
    constructor( props ) {
        super( ...arguments );
    }

    render() {
        const { attributes } = this.props; /* attributes passed from parent component */
        const { width, height } = attributes;

        return (
           doMath(width, height);
        )
    }
}

将内部渲染作为const:

class MyClass extends Component {
    constructor( props ) {
        super( ...arguments );
    }

    render() {
        const { attributes } = this.props; /* attributes passed from parent component */
        const { width, height } = attributes;

        const doMath = (width, height) {
           const result = 100 / (width / height);
           return result;
        }

        return (
           doMath(width, height);
        )
    }
}

似乎我也可以将其添加到componentDidMountcomponentDidUpdate

据我了解,在render()中添加它是一种不好的做法,但它似乎无处不在。在这种情况下,最佳做法是什么?

3 个答案:

答案 0 :(得分:3)

第三种方法肯定不行。在每次render方法内添加该函数将创建一个新的doMath函数,每次您重新提交组件时,但这不是一种行之有效的方法。

如果您确定只将doMath函数用于此特定组件,则建议您在组件的模块中对其进行定义而不导出。所以我会选择第二种方式。

如果该函数仅依赖于widthheight,那么最好将其置于组件类之外。否则,如果您认为它可能取决于state的更多部分,则可以将其放在类中,这样就不必强迫传递组件的状态。

结论:根据要传递给doMath函数的数据量,可以在类内部或外部创建数据;但绝对不能使用render方法。


编辑:我忘记提及的是使用static方法。基本上,如果您未设置方法static,则将为组件的每个实例创建该方法,并将能够使用其他类成员:

(A)如果方法不是static

class MyComponent extends React.Component {
  /* private */ doMath() {
    // You have access to this particular instance and its state
    const {width, height} = this.state; 
  }
}

(B)如果该方法是静态的:

class MyComponent extends React.Component {
  /* private */ static doMath(width, height) {
    // do something with them
    // no access to state or the component's instance
  }

  render() {
    const {width, height} = this.state;

    const result = MyComponent.doMath(width, height);

    // render something
  }
}

(C)为了完整起见,让我们在类之外定义函数:

function doMath(width, height) {
  // do magic
  return result;
}

class MyComponent extends React.Component {
  render() {
    const {width, height} = this.state;
    const result = doMath(width, height);

    // render something
    // use result
  }
}

// emphasize export
module.exports = MyComponent;

比较

使用类似TypeScript的方法时,方法(B)和(C)基本上得到相同的结果:您可以通过指定static方法private来隔离功能。但是,在使用JavaScript时,我更喜欢(C),因为如果这样做

const MyComponent = require('/path/to/MyComponent');
MyComponent.doMath(); // undefined

我不能使用doMath函数,因为我不应该这样做。使用这两种方法,您需要将所需的数据作为参数传递给函数/方法(即,您无权访问组件实例的内部状态)。

现在,对于(A),将为该组件的每个实例创建该方法(如果您有很多实例,可能要考虑一些问题)。您将可以访问this(因此可以访问组件的内部状态),而不必传递任何内容作为参数,如果不确定该方法需要多少数据,这可能很方便。

我希望您能从这个解释中得出结论。

答案 1 :(得分:3)

这3种方法的最佳方法是在类内部,因为这样其他组件便可以通过math函数重用该组件。如果您在组件外部执行此操作,则该功能将不再与组件绑定。但是,由于Hooks是使所有组件都具有状态的新事物,因此将来很有可能Class类组件将过时并且不再接收更新。如果函数在钩子版本中变为无状态之前是无状态的,那么您应该阅读它是一件好事!

答案 2 :(得分:0)

只需将其放在类中,并在渲染方法中通过{this.doMath()}进行调用

class MyClass extends Component {
    constructor( props ) {
        super( ...arguments );
    }

    doMath() {
       const { width, height } = this.props.attributes;
       const result = 100 / (width / height);
       return result;
    }

    render() {
        const { attributes } = this.props; /* attributes passed from parent component */
        const { width, height } = attributes;

        return (
           {this.doMath()}
        )
    }
}