如何为反应组件方法绑定“this”

时间:2017-07-20 17:48:05

标签: javascript reactjs

我无法理解为什么需要 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_master); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) .setAction("Action", null).show(); } }); DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); drawer.setDrawerListener(toggle); toggle.syncState(); NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); navigationView.setNavigationItemSelectedListener(this); FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser(); if (currentUser == null) { startActivity(AuthActivity.createIntent(this)); finish(); return; } else{ // TODO: 02/07/2017 check if data user dengan nomor telpon ini sudah ada atau belum, kalau belum didaftarkan ke data user } mIdpResponse = IdpResponse.fromResultIntent(getIntent()); mSignedInConfig = getIntent().getParcelableExtra(EXTRA_SIGNED_IN_CONFIG); View headerLayout = navigationView.inflateHeaderView(R.layout.nav_header_master); mUserDisplayName = ButterKnife.findById(headerLayout, R.id.tv_name); mUserPhoneNumber = ButterKnife.findById(headerLayout, R.id.tv_phone); populateProfile(); handleInstanceState(savedInstanceState); setupFirebase(); setupRecyclerview(); } private void setupRecyclerview() { FrameLayout layoutInclude = (FrameLayout)findViewById(R.id.layout_include); //application always terminated here FrameLayout layoutContent = (FrameLayout)layoutInclude.findViewById(R.id.layout_content); RecyclerView recyclerView = (RecyclerView) layoutContent.findViewById(R.id.recyclerview); mNearbyAdapter = new NearbyAdapter(mQuery, mAdapterItems, mAdapterKeys); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setAdapter(mNearbyAdapter); } 以及它在做什么。

this.click = this.click.bind(this)

4 个答案:

答案 0 :(得分:4)

如果您没有使用bind(),则从事件监听器调用this.click()时,this的值不会是您的React组件(其中stateprops等),而this本身就是函数this.click()。通常,每次调用函数时,执行上下文 - this的值 - 都会设置为函数本身。

当然,如果你想访问你的React组件的上下文,这不是一件好事。 bind()是确保函数与组件的相同执行上下文一起运行的一种方法,使您可以访问函数内的this.statethis.props等。另一种方法是使用ES6箭头函数声明:

let foo = () => {console.log("bar")}

自动将this的值foo设置为声明函数的任何上下文。如果在与React组件相同的上下文中声明foo,它将保留上下文,从而确保thisfoo的值相同。

答案 1 :(得分:2)

您需要这样做,因为使用不同的context调用回调函数。通过执行.bind( this ),您可以确保始终使用与您的组件相同的this context来调用该函数。

Editted:per @ jered的评论。

答案 2 :(得分:2)

必须使用React Documentation绑定,因为默认情况下不会绑定类方法。如果你将回调传递给没有绑定的事件处理程序,'this'将是未定义的。

您可以使用属性初始值设定项来绑定回调:

class MyComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            name: 'Initial State'
        };
    }
    handleClick = () => {
        this.setState({
            name: 'React Rocks!'
        });
    }
    render() {
        return (
          <div>
          <button onClick = {this.handleClick}>Click Me</button>
          <h1>{this.state.name}</h1>
          </div>
      );
    }
};

您还可以在回调中使用箭头功能

class MyComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            name: 'Initial State'
        };
    }
    handleClick() {
        this.setState({
            name: 'React Rocks!'
        });
    }
    render() {
        return (
          <div>
          <button onClick = {() => this.handleClick()}>Click Me</button>
          <h1>{this.state.name}</h1>
          </div>
      );
    }
};

答案 3 :(得分:1)

如果没有它,您应该在调用click()函数时未定义。来自反应文档...

  

在JSX回调中你必须要小心这个含义。在   JavaScript,类方法默认不受约束。如果你忘记了   绑定this.handleClick并将其传递给onClick,这将是未定义的   当实际调用该函数时。

在此处查看文档以获取更多详细信息:https://facebook.github.io/react/docs/handling-events.html