React - 使用JavaScript设置输入值不会触发'onChange'

时间:2017-02-17 03:23:49

标签: javascript reactjs

在我的React应用程序(版本15.4.2)中,我使用JavaScript更新文本输入字段的值 - 但是,我有一个与输入字段关联的onChange事件侦听器,并更改了值虽然字段的内容已正确更新,但输入字段不会触发处理程序(输入字段中的旧式输入确实很好)。

constructor(props) {
    super(props);
    this.onChange = this.onChange.bind(this);
}

onChange(event){
    let attribute = event.target.name;
    let updatedGroup = this.state.group;
    updatedGroup[attribute] = event.target.value;
    this.setState({group: updatedGroup});
}

addMember(memberId) {
    let inputField = document.getElementById("members");
    let inputValues = inputField.value.split(",");
    inputField.value = [...inputValues, memberId];
}

render(){
    <input type="text" id="members" name="members" value={this.state.group.members} onChange={this.onChange} />
}

因此,当调用addMember()时(通过子组件中的按钮单击),输入字段本身的内容将被正确更新,但不会调用onChange,因此状态不会更新等等...

有没有办法可以编程方式设置输入字段的值并触发onChange

2 个答案:

答案 0 :(得分:1)

Onchange方法仅在您输入内容时才会被触发,如果您使用document.getElementById并替换其值,则会直接替换DOM中的值,onChange将不会被触发那种情况。既然你正在使用反应,我认为你应该避免直接的DOM操作。

您正在使用受控输入,因此在addMember方法而不是更新DOM中的值时,请更新state值。

试试这个addmember方法:

addMember(memberId) {
    //let inputField = document.getElementById("members");
    //let inputValues = inputField.value.split(",");
    //inputField.value = [...inputValues, memberId];

    let group = this.state.group.slice();
    group[members] = group[members] + ',' + memberId;
    this.setState({
        group
    });
}

答案 1 :(得分:1)

在这种情况下我总是做的是让 public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { private int REQUEST_CAMERA = 0, SELECT_FILE = 1; private Button btnSelect; private ImageView ivImage; private String userChoosenTask; private SharedPreferences pref, pref2; private String jsonResult; public static Boolean isBookmarkSelected = false; private String url = "http://nwbrn.ayz.pl/Bookmark.php"; private Menu menu; private MenuItem starMenu; private MenuItem shareMenu; private Bookmark bookmark; private TextView textView; private TextView textView2; private TextView textView3; private TabLayout tabLayout; private ViewPager viewPager; private FloatingActionButton floatingActionButton1, floatingActionButton2, floatingActionButton3; public static FloatingActionMenu materialDesignFAM; public static boolean fabVisible; private static final String TAG = MainActivity.class.getSimpleName(); private BroadcastReceiver mRegistrationBroadcastReceiver; private TextView txtRegId, txtMessage; private int[] tabIcons = { R.drawable.ic_tab_one, R.drawable.ic_tab_two, R.drawable.ic_tab_profile }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); FirebaseApp.initializeApp(this); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); getSupportActionBar().setDisplayShowTitleEnabled(false); getSupportActionBar().setDisplayHomeAsUpEnabled(false); // getSupportActionBar().setDisplayUseLogoEnabled(true); // getSupportActionBar().setDisplayShowHomeEnabled(true); getSupportActionBar().setIcon(R.drawable.logo2); // txtRegId = (TextView) findViewById(R.id.txt_reg_id); // txtMessage = (TextView) findViewById(R.id.txt_push_message); pref = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); String name = pref.getString(Constants.NAME, ""); String avatar = pref.getString(Constants.AVATAR, ""); textView = (TextView) findViewById(R.id.textView); textView2 = (TextView) findViewById(R.id.textView2); textView3 = (TextView) findViewById(R.id.textView3); textView.setText(pref.getString(Constants.FULLNAME, "")); textView2.setText("@" + pref.getString(Constants.NAME, "")); Spannable span = new SpannableString("made with by @Marcin.Brzozowski"); // or set your text manually Drawable drawable; drawable = getResources().getDrawable(R.drawable.madewithlove_heart); drawable.setBounds(8, 8, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); ImageSpan imageSpan = new ImageSpan(drawable); span.setSpan(imageSpan, 9, 11, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); textView3.setText(span); FirebaseInstanceId.getInstance().getToken(); mRegistrationBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // checking for type intent filter if (intent.getAction().equals(Config.REGISTRATION_COMPLETE)) { // gcm successfully registered // now subscribe to `global` topic to receive app wide notifications FirebaseMessaging.getInstance().subscribeToTopic(Config.TOPIC_GLOBAL); // displayFirebaseRegId(); } else if (intent.getAction().equals(Config.PUSH_NOTIFICATION)) { // new push notification is received String message = intent.getStringExtra("message"); Toast.makeText(getApplicationContext(), "Push notification: " + message, Toast.LENGTH_LONG).show(); // txtMessage.setText(message); } } }; // displayFirebaseRegId(); // textView3.setText("Made with love by MB"); // textView3.setGravity(Gravity.CENTER | Gravity.RIGHT); ivImage = (ImageView) findViewById(R.id.ivImage); // Picasso.with(getBaseContext()).invalidate(pref.getString(Constants.AVATAR, "")); Picasso.with(getBaseContext()) .load(Uri.parse(pref.getString(Constants.AVATAR, ""))) .resize(200, 200).centerCrop() .memoryPolicy(MemoryPolicy.NO_CACHE ) .networkPolicy(NetworkPolicy.NO_CACHE) .noFade() .into(ivImage); final String[] menus = {"Home", "My Groups", "Change Group", "Settings"}; 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(); final TabsFragment galleryFragment = new TabsFragment(); getSupportFragmentManager().beginTransaction() .replace(R.id.content_frame, galleryFragment) .addToBackStack(null) .commit(); elevateActionBar(false); NavigationView navigationView = (NavigationView) findViewById(R.id.navigation); navigationView.setNavigationItemSelectedListener(this); //CustomAdapter we created for Customize Navigation ListView navlist = (ListView) findViewById(R.id.list); NavPanelListAdapter adapter = new NavPanelListAdapter(this, menus); navlist.setAdapter(adapter); navlist.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { String selectedMenu = menus[i]; switch (selectedMenu) { case "Home": // TabsFragment groupFragment = new TabsFragment(); getSupportFragmentManager().beginTransaction() .setCustomAnimations(R.anim.enter,R.anim.exit,R.anim.pop_enter, R.anim.pop_exit) .replace(R.id.content_frame, galleryFragment) .addToBackStack(null) .commit(); elevateActionBar(false); break; case "My Groups": MyGroupsFragment groupsFragment = new MyGroupsFragment(); getSupportFragmentManager().beginTransaction() .setCustomAnimations(R.anim.enter,R.anim.exit,R.anim.pop_enter, R.anim.pop_exit) .replace(R.id.content_frame, groupsFragment) .addToBackStack(null) .commit(); elevateActionBar(true); break; case "Change Group": ChangeGroupFragment changeGroupFragment = new ChangeGroupFragment(); getSupportFragmentManager().beginTransaction() .setCustomAnimations(R.anim.enter,R.anim.exit,R.anim.pop_enter, R.anim.pop_exit) .replace(R.id.content_frame, changeGroupFragment) .addToBackStack(null) .commit(); elevateActionBar(true); break; case "Settings": SettingsFragment settingsFragment = new SettingsFragment(); getSupportFragmentManager().beginTransaction() .setCustomAnimations(R.anim.enter,R.anim.exit,R.anim.pop_enter, R.anim.pop_exit) .replace(R.id.content_frame, settingsFragment) .addToBackStack(null) .commit(); elevateActionBar(true); break; default: break; } DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); drawer.closeDrawer(GravityCompat.START); } }); } @Override public void onBackPressed() { DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); if (drawer.isDrawerOpen(GravityCompat.START)) { drawer.closeDrawer(GravityCompat.START); } else { super.onBackPressed(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { this.menu = menu; String email = pref.getString(Constants.EMAIL, ""); System.out.println(email); String id_group = pref.getString(Constants.ID_GROUP, ""); System.out.println(id_group); String _nameOfGroup = pref.getString(Constants.NAZWA, ""); System.out.println(_nameOfGroup); onBookmarkItemSelected(email, id_group, _nameOfGroup); starMenu = menu.add("Added to Favourites"); shareMenu = menu.add("Share files."); shareMenu.setIcon(R.drawable.share).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); if(isBookmarkSelected == true) { starMenu.setIcon(R.drawable.ic_star_black).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); } else { starMenu.setIcon(R.drawable.ic_star_border_black).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); } getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.action_settings) { startActivity(new Intent(getBaseContext(), SettingsActivity.class)); } if (id == R.id.logout) { SharedPreferences.Editor editor = pref.edit(); editor.putBoolean(Constants.IS_LOGGED_IN,false); editor.putString(Constants.EMAIL,""); editor.putString(Constants.NAME,""); editor.putString(Constants.UNIQUE_ID,""); editor.putString(Constants.AVATAR, ""); editor.apply(); startActivity(new Intent(getBaseContext(), LoginActivity.class)); } if(item == shareMenu) { // ContentValues values = new ContentValues(); // values.put(BluetoothShare.URI, "content://" + uritoSend); // values.put(BluetoothShare.DESTINATION, deviceAddress); // values.put(BluetoothShare.DIRECTION, BluetoothShare.DIRECTION_OUTBOUND); } if(item == starMenu) { new IsStarSelected(bookmark, pref.getString(Constants.ID_GROUP, "")); if (isBookmarkSelected == false) { starMenu.setIcon(R.drawable.ic_star_black).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); Toast.makeText(getApplicationContext(), "Added to favorites!", Toast.LENGTH_SHORT).show(); // FirebaseMessaging.getInstance().unsubscribeFromTopic(pref.getString(Constants.ID_GROUP, "")); } else { starMenu.setIcon(R.drawable.ic_star_border_black).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); Toast.makeText(getApplicationContext(), "Removed from favorites!", Toast.LENGTH_SHORT).show(); // FirebaseMessaging.getInstance().subscribeToTopic(pref.getString(Constants.ID_GROUP, "")); } } return super.onOptionsItemSelected(item); } @SuppressWarnings("StatementWithEmptyBody") @Override public boolean onNavigationItemSelected(MenuItem item) { // Handle navigation view item clicks here. int id = item.getItemId(); if (id == R.id.groups_nav) { MyGroupsFragment tabsFragment = new MyGroupsFragment(); getSupportFragmentManager().beginTransaction() .replace(R.id.content_frame, tabsFragment) .addToBackStack(null) .commit(); elevateActionBar(true); } else if (id == R.id.change_group_nav) { ChangeGroupFragment changeGroupFragment = new ChangeGroupFragment(); getSupportFragmentManager().beginTransaction() .setCustomAnimations(R.anim.enter,R.anim.exit,R.anim.pop_enter, R.anim.pop_exit) .replace(R.id.content_frame, changeGroupFragment) .addToBackStack(null) .commit(); elevateActionBar(true); } else if (id == R.id.settings_nav) { SettingsFragment settingsFragment = new SettingsFragment(); getSupportFragmentManager().beginTransaction() .setCustomAnimations(R.anim.enter, R.anim.exit, R.anim.pop_enter, R.anim.pop_exit) .replace(R.id.content_frame, settingsFragment) .addToBackStack(null) .commit(); elevateActionBar(true); } DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); drawer.closeDrawer(GravityCompat.START); return true; } public void onBookmarkItemSelected(String email, String id_group, String _nameOfGroup) { OkHttpClient.Builder okHttpClient = new OkHttpClient.Builder(); HttpLoggingInterceptor debugger = new HttpLoggingInterceptor() .setLevel(HttpLoggingInterceptor.Level.BODY); okHttpClient .addInterceptor(debugger); Retrofit retrofit = new Retrofit.Builder() .baseUrl(Constants.BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .client(okHttpClient.build()) .build(); RequestInterface requestInterface = retrofit.create(RequestInterface.class); Integer id_int_group = Integer.parseInt(id_group); bookmark = new Bookmark(email, id_int_group, _nameOfGroup); ServerRequest request = new ServerRequest(); request.setOperation(Constants.BOOKMARK_OPERATION); request.setBookmark(bookmark); Call<ServerResponse> response = requestInterface.operation(request); response.enqueue(new Callback<ServerResponse>() { @Override public void onResponse(Call<ServerResponse> call, retrofit2.Response<ServerResponse> response) { ServerResponse resp = response.body(); if (resp.getResult().equals(Constants.SUCCESS)) // Log.d(Constants.TAG, "success"); isBookmarkSelected = true; else isBookmarkSelected = false; if (isBookmarkSelected == true) starMenu.setIcon(R.drawable.ic_star_black).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); else starMenu.setIcon(R.drawable.ic_star_border_black).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); } @Override public void onFailure(Call<ServerResponse> call, Throwable t) { // progress.setVisibility(View.INVISIBLE); Log.d(Constants.TAG, "failed", t); // Snackbar.make(getView(), t.getLocalizedMessage(), Snackbar.LENGTH_LONG).show(); } }); } private void elevateActionBar(boolean elevate){ //Elevate ActionBar (make ActionBar have a shadow) AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.appBar); if(elevate) { appBarLayout.setElevation(7); } else{ appBarLayout.setElevation(0); } } @Override protected void onResume() { super.onResume(); // register GCM registration complete receiver LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver, new IntentFilter(Config.REGISTRATION_COMPLETE)); // register new push message receiver // by doing this, the activity will be notified each time a new message arrives LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver, new IntentFilter(Config.PUSH_NOTIFICATION)); // clear the notification area when the app is opened NotificationUtils.clearNotifications(getApplicationContext()); } @Override protected void onPause() { LocalBroadcastManager.getInstance(this).unregisterReceiver(mRegistrationBroadcastReceiver); super.onPause(); } 事件处理程序成为将事件数据(输入的字符或聚合字符串)传递到另一个函数的函数。我将所有业务逻辑放在 函数中。这样,如果我想调用业务逻辑,我只需要调用该方法。

因为你问“有没有办法我可以以编程方式设置输入字段的值并触发onChange?”为什么不跳过onChange并从以编程方式设置值的函数调用业务逻辑函数?