React函数的行为不符合预期

时间:2019-11-04 09:04:43

标签: javascript reactjs

这里有我的React应用中的功能:

handleSubmit(evt) {
  evt.preventDefault();
  this.setState({
    width: "",
    height: "",
    color: ""
  });
  console.log(this.state)
};

在输入中,我将输入的值设置为宽度,高度和颜色。填写表单后,就会发生此handleSubmit函数。

但是我已经通过setState行之前的console.log设置了状态。因此,它将在调用console.log之前替换表单中的值。我应该得到

{width :" ", height :" ", color :" "} 

但是,我得到了由输入设置的值。但是似乎setState仅在完成全部功能时才起作用,而不在日志之前起作用。为什么?

2 个答案:

答案 0 :(得分:7)

  

但是似乎setState仅在完成完整功能时才起作用,而不是在日志之前起作用。为什么?

setState不会立即更改状态。参考:https://reactjs.org/docs/react-component.html#setstate

如果您想在状态更改后立即做某事,请使用回调函数。

handleSubmit(evt) {
  evt.preventDefault();
  this.setState({
    width: "",
    height: "",
    color: ""
  }, () => {
    console.log(this.state)
  });
};

答案 1 :(得分:1)

您可以使用功能性setState而不是传递对象。相反,您可以向setState传递一个函数,该函数以当前状态和prop作为参数,此函数返回一个将合并到旧状态的对象。

例如,

public class LoginActivity extends Activity {
        private static final String DB_NAME = "BD.db";
        private EditText txtUsername;
        private EditText txtPassword;
        private SQLiteDatabase database;
        private  ExternalDbOpenHelper dbOpenHelper;
        private com.it.bdrelease.Log  errorlog;
     private String errorMessage;
     private  GlobalClass global;
     private String strSalespersonID;
     private Cursor cursor;
     private SharedPreference sharedPreference;
     private Activity context = this;

 @SuppressWarnings("deprecation")
 @Override
 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);
    Resources res = getResources();
    Drawable shape = res.getDrawable(R.drawable.buttonbackground);
    Button loginbutton = (Button) findViewById(R.id.ok);
    loginbutton.setBackgroundDrawable(shape);
    final ActionBar actionBar = getActionBar();
    actionBar.setBackgroundDrawable(getResources().getDrawable(R.drawable.headbg));
    actionBar.setTitle(Html.fromHtml("<font color='#ff0000'>Business Development </font>"));
    dbOpenHelper = new ExternalDbOpenHelper(this, DB_NAME);
    database = dbOpenHelper.openDataBase();
    sharedPreference = new SharedPreference();
    addListenerOnOkButton();
    txtUsername = (EditText) findViewById(R.id.username);
    txtPassword = (EditText) findViewById(R.id.password);
    txtUsername.setText("xxxxx@hotmail.com");
 }
 public void addListenerOnOkButton()
{
    final Context context = this;
    Button okButton = (Button) findViewById(R.id.ok);
    okButton.setOnClickListener(new  View.OnClickListener() {
        @Override
        public void onClick(View v) {
            try {

            if(txtUsername.getText().toString().trim().length() > 0 && txtPassword.getText().toString().trim().length() > 0)
          {
              String strUserName = txtUsername.getText().toString().trim();
              String strPassword = txtPassword.getText().toString().trim();
              cursor= database.query("tblUsers", null, "UserName='" + strUserName + "' and Password='" + strPassword  + "'" , null, null, null, null);
                if(cursor.getCount()<1) // UserName Not Exist
                {
                      Toast.makeText(getApplicationContext(), "Invalid username and password.", Toast.LENGTH_LONG).show();
                }
            else
                {       cursor.moveToFirst();
                        String SalespersonID =cursor.getString(0);
                        String SalespersonName = cursor.getString(2);
                        sharedPreference.save(context, SalespersonID);
                        GlobalClass global;
                        global=((GlobalClass)getApplicationContext());
                        global.setSalespersonId(SalespersonID);
                        global.setName(SalespersonName);
                        GlobalClass.SalespersonID=SalespersonID;
                        Intent intent = new Intent(context, BdActivity.class);
                        startActivity(intent);
                        clear();
                }
              }
        else
        {
           Toast.makeText(getApplicationContext(), "Enter username and password.", Toast.LENGTH_LONG).show();
                }
        } catch (Exception e) {
                    Toast.makeText(getApplicationContext(), "Error encountered:" + e, Toast.LENGTH_LONG).show();
                              }
              finally
               {
                   cursor.close();
               }
         }
   });
}
public void clear()
{
    txtUsername.setText("");
    txtPassword.setText("");
    txtUsername.requestFocus();
}
@Override
 public void onBackPressed() {
  // TODO Auto-generated method stub
  //super.onBackPressed();
 // openQuitDialog();
    // Toast.makeText(getApplicationContext(), "Tested ok ", Toast.LENGTH_SHORT).show();
    //database.close();
    finish();
 }

对setState的调用被排队,然后按照被调用的顺序执行。执行它们时,该功能将接收最新状态,而不是接收旧状态。