Updating Functional Component Local State Using Data From Redux State

强颜欢笑 提交于 2021-01-28 08:01:29

问题


I'm building contact manager. When the user clicks the update button for a specific contact an action is dispatched and the "hotContact" property in the reducer's state is populated with an object. What I want is the fields of the ContactForm to be populated with the name and number of the "hotContact". However, despite the hotContact being loaded into the redux state my ContactForm component won't display the name and number of the hotContact. How can I proceed? This is what I have so far.

I tried calling setFormData in a conditional block to check if hotContact is present and loadingHotContact is false, but that just gives me an infinite re-render error.

import React, { useState } from 'react';
import { connect } from 'react-redux';
import { addContact, updateContact } from '../actions/contacts';

const ContactForm = ({
  addContact,
  updateContact,
  contacts: { hotContact, loadingHotContact },
}) => {


  const [formData, setFormData] = useState({
    name:
      hotContact === null && loadingHotContact
        ? ''
        : hotContact.name,
    number:
      hotContact === null && loadingHotContact
        ? ''
        : hotContact.number,
  });

  const onFormDataChange = (event) => {
    setFormData({ ...formData, [event.target.name]: event.target.value });
  };

  const { name, number } = formData;

  const handleSubmit = (event) => {
    event.preventDefault();
    const newContact = { name, number };
    addContact(newContact);
    console.log('Submit the form!');
    setFormData({ name: '', number: '' });
  };

  const handleUpdateSubmit = (event) => {
    event.preventDefault();
    const updatedContact = { name, number };
    updateContact(hotContact._id, updatedContact);
  };


  return !hotContact ? (
    <form onSubmit={handleSubmit}>
      <div>
        Name{' '}
        <input
          type='text'
          name='name'
          value={name}
          onChange={(event) => onFormDataChange(event)}
        />
      </div>
      <div>
        Number{' '}
        <input
          type='text'
          name='number'
          value={number}
          onChange={(event) => onFormDataChange(event)}
        />
      </div>
      <input type='submit' value='Add Contact' />
    </form>
  ) : (
    <form onSubmit={handleUpdateSubmit}>
      <div>
        Name{' '}
        <input
          type='text'
          name='name'
          value={name}
          onChange={(event) => onFormDataChange(event)}
        />
      </div>
      <div>
        Number{' '}
        <input
          type='text'
          name='number'
          value={number}
          onChange={(event) => onFormDataChange(event)}
        />
      </div>
      <input type='submit' value='Apply Changes' />
    </form>
  );
};

const mapStateToProps = (state) => ({
  contacts: state.contacts,
});
export default connect(mapStateToProps, { addContact, updateContact })(
  ContactForm
);

回答1:


This doesn't work because at the first renderer useState is initialized with the hotContact from the props, but when you receive the new value from the props the state doesn't update (that's how the useState hook works)

If you want to update your state you should use the useEffect hook:

const ContactForm = ({
  addContact,
  updateContact,
  contacts: { hotContact, loadingHotContact },
}) => {

  const [formData, setFormData] = useState({
    name:
      hotContact === null && loadingHotContact
        ? ''
        : hotContact.name,
    number:
      hotContact === null && loadingHotContact
        ? ''
        : hotContact.number,
  });

  useEffect(() => {
    const {name, number} = props.hotContact;
    setFormData({
      name: name || '',
      number: number || '',
    });
    // execute this
  }, [hotContact]); // when hotContact changes
}

Also, I think you may simplify you assignment this way:

const {name, number} = props.hotContact;

setFormData({
  name: name || '',
  number: number || '',
});


来源:https://stackoverflow.com/questions/62459676/updating-functional-component-local-state-using-data-from-redux-state

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!