首页 > 解决方案 > 使用和不使用构造函数将函数传递给状态的差异

问题描述

我正在学习 React 的 Context 并且我正在查看的材料基本上使用了构造函数,我试图变得幻想,看看我是否可以在没有构造函数的情况下完成它,这就是我想出的有效方法。但是在这个过程中,我意识到我对几个关键概念没有扎实的理解,工作代码基本上只是反复试验的结果!

以下是我所知道的:

这是我需要解释的内容:

我知道我在 App 组件中设置了两次状态,这是为了展示两种不同的方法。

提供者组件:

const UserData = React.createContext();

class App extends Component {

  // classic approach
  constructor(props) {
    super(props);

    this.state = {
      name: 'Rick',
      toggleName: this.toggleName
    };
  }

   // alternate approach
   state = {
     name: 'Rick',
     toggleName: () => this.toggleName()
   };

  toggleName = () => {
    this.setState(state => ({
      name: state.name === 'Rick' ? 'Morty' : 'Rick'
    }));
  };

  render() {
    return (
      <UserData.Provider value={this.state}>
        {/* ... rest of code */}
      </UserData.Provider>
    );
  }
}

以及消费者组件:

const ConsumerComponent = () => (
  <UserData.Consumer>
    {({ name, toggleName }) => (
      <div onClick={toggleName}>
        {name}
      </div>
    )}
  </UserData.Consumer>
);

标签: javascriptreactjsecmascript-6

解决方案


在“替代”方法中需要包装函数的原因是因为您试图引用尚未初始化的东西。这是类“属性”与类“方法”不同的方式之一,类“方法”在构造函数运行时已经附加到类引用。只需更改语句的顺序即可使其工作:

class App extends Component {
  toggleName = () => {
    this.setState(state => ({
      name: state.name === 'Rick' ? 'Morty' : 'Rick'
    }));
  };

   // alternate approach
   state = {
     name: 'Rick',
     toggleName: this.toggleName // now it is initialized
   };


  render() {
    return (
      <UserData.Provider value={this.state}>
        {/* ... rest of code */}
      </UserData.Provider>
    );
  }
}

例子


推荐阅读