我有一个简单的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);
)
}
}
似乎我也可以将其添加到componentDidMount
或componentDidUpdate
据我了解,在render()
中添加它是一种不好的做法,但它似乎无处不在。在这种情况下,最佳做法是什么?
答案 0 :(得分:3)
第三种方法肯定不行。在每次render
方法内添加该函数将创建一个新的doMath
函数,每次您重新提交组件时,但这不是一种行之有效的方法。
如果您确定只将doMath
函数用于此特定组件,则建议您在组件的模块中对其进行定义而不导出。所以我会选择第二种方式。
如果该函数仅依赖于width
和height
,那么最好将其置于组件类之外。否则,如果您认为它可能取决于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()}
)
}
}