【问题标题】:The name of static method in javascript should not be duplicated?javascript中静态方法的名称不应该重复吗?
【发布时间】:2017-12-24 14:58:21
【问题描述】:

我正在使用 React Native 制作应用程序。 最困难的部分是处理 javascript。我使用 Xamarin.Forms 制作了几个应用程序。现在我被 React Native 所吸引。

顺便说一句。

当我打电话时 console.log('I should be given B', B.getInstance()) 在 App.js 文件中。

我不明白为什么我得到了 A 的实例而不是 B 的实例,即使我调用了 B 的静态方法。

谢谢。

[Root.js]

import App from './App'
import A from './A'

export default class Root extends React.Component{
    render(){
        return (
            <View>
                <App/>
                <A/>
            </View>
        )
    }
}

[App.js]

import A from './A'
import B from './B'

export default class App extends React.Component{
    componentDidMount(){
        console.log('I should be given B', B.getInstance())
        //*************** BUT I get A's instance!!!!!!! ****************
    }

    render(){
        return (
            <View>
                <A/>
                <B/>
            </View>
        )
    }
}

[A.js]

import React from 'react'
import { Text } from 'react-native';

export default class A extends React.Component{
    static instance = null;
    static getInstance(){
        return A.constructor.instance;
    }

    title = 'I\'m A';

    componentWillMount(){
        A.constructor.instance = this;
    }
    render(){
        return <Text>I'm A</Text>
    }
}

[B.js]

import React from 'react'
import { Text } from 'react-native';

export default class B extends React.Component{
    static instance = null;
    static getInstance(){
        return B.constructor.instance;
    }

    title = 'I\'m B';

    componentWillMount(){
        B.constructor.instance = this;
    }
    render(){
        return <Text>I'm B</Text>
    }
}

【问题讨论】:

  • 你想用你的组件中的实例来完成什么?
  • 这只是一个例子。我唯一的好奇是为什么我得到 A 的实例而不是 B 的实例。
  • 我对 JavaScript 中的类还不太了解,但根据我有限的知识,构造函数是一种方法,而不是你应该放东西的垃圾对象。所以你需要的只是return B.instance。其中 B.instance 实际上不是真正的静态类属性,因为 JavaScript 不支持它。而且您应该刚刚编辑了上一个问题,这不是一个不同的问题。
  • 而且我不了解 React(最佳)实践,但使用 getInstance 对我来说意义不大。您可能应该在您的班级下方写export default new B(),而不是导出您的班级。或者让一些全局类保留对实例的所有引用。
  • 嗨@René 我同意我应该编辑我以前的问题,但是如果我把所有东西都放在那里,我担心它会很乱而且已经有了答案,所以我担心答案似乎是错误的,即使我的问题可能是错误的。无论如何,使用构造函数是在 javascript 中访问内部静态成员的正确方法。它可能看起来很奇怪,因为我也有同样的想法。

标签: javascript reactjs react-native


【解决方案1】:

B.constructorA.constructor 引用同一个对象 在 JS 函数中也是对象 所以如果更改 B 中的一些数据.constructor 也会影响A.constructor

详细

为了弄清楚当前的情况,让我们忘记 React 和 Classes。 你正在尝试做的看起来像这样:

const constructor = () => {} //  'constructor' is just a demonstrative it can be anything else as other variables

const A = {
  constructor,
  componentDidMount(){ // Again could be anything alse than 'componentDidMount'
    A.constructor.instance = 'A instance';
  }
}
const B = {
  constructor,
  componentDidMount(){ // Again could be anything alse than 'componentDidMount'
    B.constructor.instance = 'B instance';
  }
}

// Now A and B are not equal to each other
// But property 'constructor' in both objects(A,B) references to the same 'constructor' function

//Now lets do what you did, In your examble you was rendering component A 2 times, and B 1 time. A -> B -> A. The last comonent was rendered is A. So what happens at that time

//render A
A.componentDidMount() // This sets constructor.instance to 'A'
console.log(A.constructor.instance);
B.componentDidMount() // This overwrites constructor.instance to 'B'|
// Now if you call 
console.log(A.constructor.instance) // This will return 'B'

// And at the last you are rendering 'A' 2th tiem
A.componentDidMount() // And this again overrides constructor.instance to 'B'

//So after this you are trying to get data from B.constructor
//which will be 'A' because A.constructor == B.constructor

为避免此问题不要将数据存储在构造函数中。 我认为您可以使用React's ref's

来解决这个问题

希望对你有帮助

【讨论】:

  • 非常感谢您的详细回答!它一定是有帮助的。我会深入研究它并将您的标记为答案。再次感谢@davo11122。
【解决方案2】:

那里发生的情况是,当您在下面的代码中引用 B

componentDidMount(){
  console.log('I should be given B', B.getInstance())
}

您引用的不是您刚刚在代码中创建的对象 B

render(){
  return (
    <View>
      <A/>
      <B/>
    </View>
  )
}

但是 javascript 函数 B(这是 B 类声明的底层),因此代码

componentWillMount(){
  B.constructor.instance = this;
}

被“翻译”成代码

 componentWillMount(){
   Function.instance = this;
 }

因为B的constructor属性是javascript原生对象Function

同样的情况发生在 A 类,来自

componentDidMount(){ 
    A.constructor.instance = this;
  }

翻译成

 componentWillMount(){
   Function.instance = this;
 }

因此,每次您设置 A.constructor.instance 或 B.constructor.instance 时,您都在设置相同的对象属性 Function.instance。

因此,如果要引用静态类成员,则不应应用构造函数关键字,只需在类内部或外部使用 ClassName.staticMemberName,即

componentWillMount(){
  B.instance = this;
}  

它会按预期工作。

【讨论】:

  • 感谢您的友好回答。它帮助我了解发生了什么。
【解决方案3】:

这就是静态方法的全部意义所在。静态方法用于在同一类的多个实例之间共享相同的方法。 (首先可能看起来有不同的类,但仔细看就会发现)。

因此,静态方法不适合您正在尝试做的事情。

据我了解,您正试图在组件之间共享某些状态。这是 react 中非常常见的需求,通常由状态管理框架(如flux、redux 或 mobx)处理。 (React refs 可以,但它不可扩展也不高效)

例如在 redux 中,你会有一个单独的状态,当 B 被渲染时会更新,然后你可以从 App.js 或任何其他组件中引用相同的状态,你可以命名它。

【讨论】:

    猜你喜欢
    • 2018-10-10
    • 2015-08-06
    • 1970-01-01
    • 2013-11-10
    • 2019-08-07
    • 1970-01-01
    • 2017-02-10
    • 1970-01-01
    • 2014-11-02
    相关资源
    最近更新 更多