React 16.3类方法与构造方法

时间:2018-05-16 04:36:50

标签: javascript reactjs class

我正在学习React 16.3,它是新的Context API。特别是Updating Context from a Nested Component。在他们的示例中,他们设置了一个在构造函数中定义的方法,而不是标准方法。

class App extends React.Component {
  constructor(props) {
    super(props);

    // What is the benefit of doing this here?
    this.toggleTheme = () => {
      this.setState(state => ({
        theme:
          state.theme === themes.dark
            ? themes.light
            : themes.dark,
      }));
    };

    this.state = {
      theme: themes.light,
      toggleTheme: this.toggleTheme,
    };
  }

  render() {
    // The entire state is passed to the provider
    return (
      <ThemeContext.Provider value={this.state}>
        <Content />
      </ThemeContext.Provider>
    );
  }
}

我所阅读的关于提升状态并将方法传递给孩子的所有内容都是使用以下模式完成的。为什么以上优先于以下?有什么不同吗?

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      theme: themes.light,
      toggleTheme: this.toggleTheme,
    };
    this.toggleTheme = this.toggleTheme.bind(this);

  }

    // Could it be done here?
    toggleTheme() {
        this.setState(state => ({
            theme:
                state.theme === themes.dark
                ? themes.light
                : themes.dark,
        }));
    };


  render() {
    // The entire state is passed to the provider
    return (
      <ThemeContext.Provider value={this.state}>
        <Content />
      </ThemeContext.Provider>
    );
  }
}

2 个答案:

答案 0 :(得分:2)

如果你使用第一种方法在构造函数中定义方法,就像这样

constructor() {
    this.toggleTheme = () => {
      this.setState(state => ({
        theme:
          state.theme === themes.dark
            ? themes.light
            : themes.dark,
      }));
    };
}

然后,当您的组件使用this.toggleTheme 作为回调时,您不必绑定this对当前组件的引用它被定义,例如另一方面,this.toggleTheme = this.toggleTheme.bind(this),如果您将toggleTheme定义为构造函数之外的方法(如第二个示例中所示),并且toggleTheme传递作为回调 ,当调用toggleTheme

时,你会得到“setState未定义”或类似的东西

此外,第一种方法toggleTheme作为实例属性添加到组件类中,这意味着每个组件实例将具有toggleTheme的单独副本,而第二种方法将其添加到原型中组件类在内存消耗方面更好,因为所有组件实例都将在原型上共享该方法

答案 1 :(得分:0)

这两种方法的区别在于:

class MyComponenet extends React.Component {
    constructor(props) {
        super(props);

        this.method = () => {
            console.log('Method');
        }
    }

    render() {
        return null;
    }
}

......和......

class MyComponenet extends React.Component {
    method() {
        console.log('Method');
    }

    render() {
        return null;
    }
}

第一种方法是使用箭头符号定义method,它自动将函数的this绑定为组件类的实例,而另一种则不然。

您可以将第二个示例更改为:

class MyComponenet extends React.Component {
    method = () => {
        console.log('Method');
    }

    render() {
        return null;
    }
}

这与第一个示例相同,但请记住,您必须启用允许此语法的transpiler选项。