使用Redux State中的数据更新功能组件的本地状态

时间:2020-06-18 21:27:29

标签: reactjs redux react-hooks react-functional-component

我正在建立联系人经理。当用户单击特定联系人的更新按钮时,将分派一个动作,并用一个对象填充还原器状态下的“ hotContact”属性。我想要的是用“ hotContact”的名称和编号填充ContactForm的字段。但是,尽管将hotContact加载到了redux状态,但我的ContactForm组件不会显示hotContact的名称和编号。我该如何进行?这就是我到目前为止所拥有的。

我尝试在条件块中调用setFormData来检查是否存在hotContact且loadingHotContact为false,但这只给我带来了无限的重新渲染错误。

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 个答案:

答案 0 :(得分:1)

这不起作用,因为在第一个渲染器useState用道具中的hotContact进行了初始化,但是当您从道具中收到新值时,状态不会更新(这就是方法useState钩子起作用)

如果要更新状态,则应使用useEffect钩子:

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
}

此外,我认为您可以通过以下方式简化作业:

const {name, number} = props.hotContact;

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