【问题标题】:Object Values Undefined in Post Request from ReactJS来自 ReactJS 的发布请求中未定义的对象值
【发布时间】:2020-02-21 01:38:40
【问题描述】:

我正在从表单的三个独立填充的小节中制作一个对象。它们是独立填充的,因为数据来自三个不同的来源:

1) 名称和地址的后端 api 2)电话号码的第三方api 3) 用户在表单中的其他字段上执行 onChange

我注意到的是,如果我提交表单时 onChange 是最后一个执行的函数,即如果输入注释或更新电子邮件地址,那么其他两个元素会删除一些数据,特别是每个源的第一个字段.

我通过创建一个基本上运行表单控制操作(基本上重置电话号码)的效果来解决这个问题,这样做可以解决问题,但显然我不想不必依赖 useState 方法并调用它不是为了解决我不明白的问题。这是一些代码。

谢谢!

const leadContext = useContext(LeadContext);

  const { clearLiens, lien, setLien, letCall, number, clearNumber, addLead, postLogics } = leadContext;



  useEffect(() => {

    if (lien !== null) {

      setRecord(lien);

    }else {
      setRecord({
        name: '',
        address:'',
        city:'',
        state:'',
        zip:'',
        plaintiff:'',
        amount:'' 
      });
    }
  }, [lien, leadContext]);

  useEffect (()=>{ 

    if(number !== null){

      setCall({phone:number});

    }else {
      setCall({phone:''});
    }
  },[number, leadContext]);

  const [ record, setRecord ] = useState({
    name: '',
    address:'',
    city:'',
    state:'',
    zip:'',
    plaintiff:'',
    amount:'',
    lienid:''
  });

  const [ call, setCall ] = useState({
        phone: ''});


  const [ open, setOpen ] = useState({
       email:'',
       lexId:'',
       compliant:'filed',
       filingStatus:'married',
       cpa: 'cpa',
       ssn:'',
       noteText:''
  });



  const onChange = e => {
    setRecord({...name, address, city, state, zip, plaintiff, amount, [e.target.name]: e.target.value });
    setCall({...phone, [e.target.name]: e.target.value });
    setOpen({...email, lexId, compliant, filingStatus, cpa, ssn, noteText, [e.target.name]: e.target.value});
  }

  const { name, address, city, state, zip, plaintiff, amount, lienid } = record
  const { phone } = call
  const { email, lexId, compliant, filingStatus, cpa, ssn, noteText } = open



  const lead = {phone, name, address, city, state, zip, plaintiff, amount, lienid, email, lexId, compliant, filingStatus, cpa, ssn, noteText }


  const clearLead = () => {
    clearNumber();
    setLien('');
    setRecord({
      name: '',
      address:'',
      city:'',
      state:'',
      zip:'',
      plaintiff:'',
      amount:'',
    });
    setCall({
      phone: ''});

    setOpen({
        email:'',
        lexId:'',
        compliant:'filed',
        filingStatus:'m',
        cpa: 'cpa',
        noteText:'',
        ssn:''
   });  

  }

  const onSubmit = e => {
      e.preventDefault();
      addLead(lead);
      clearAll();
    };  

  const clearAll = () => {
      clearLiens();
      clearLead();
    };

  const onClick = e => {
    letCall(number);
  }

letCall(number) 是我在表单字段之一上基本上调用设置状态的热修复。我也不能将它堆叠到我的提交中,所以它必须作为一个单独的函数来完成。

const addLead = async lead => {
    const config = {
      headers: {
        'Content-Type': 'application/json'
      }
    };

      const { phone, name, address, city, state, zip, plaintiff, amount, lienid, email, lexId, compliant, filingStatus, cpa, ssn, noteText } = lead


      const noteId = uuidv4();

      const notes = [{ id : noteId,
                       note : noteText,
                       notePostedBy: ''
                    }]  

      const steve = {phone, name, address, city, state, zip, plaintiff, amount, lienid, email, lexId, compliant, filingStatus, cpa, ssn, notes }
      console.log(lead,'1');
      console.log(steve,'1');
      const res = await axios.post('/api/leads/', steve, config);

      dispatch({
        type: POST_LEAD,
        payload: res.data
      });

  };

【问题讨论】:

    标签: reactjs react-hooks


    【解决方案1】:

    看起来这与您在onChange 中更新状态值的方式有关。具体来说,你写:

    setRecord({...name, address, city, state, zip, plaintiff, amount, [e.target.name]: e.target.value });
    

    但由于name 不可传播,它变成了一个空值,因此更新后的record 状态将没有name 的值(除非name 是更改后的输入)。

    要解决此问题,您可以通过以下方式简化更新:

    const onChange = e => {
        setRecord(prev => ({...prev, [e.target.name]: e.target.value}));
        setCall(prev => ({...prev, [e.target.name]: e.target.value}));
        setOpen(prev => ({...prev, [e.target.name]: e.target.value}));
    }
    

    但是,您可能还想添加某种检查来更新正确的状态对象,这样键就不会被放入所有状态对象中。比如:

    const onChange = e => {
        if (Object.keys(record).includes(e.target.name) {
            setRecord(prev => ({...prev, [e.target.name]: e.target.value}));
        }
        // and so on...
    }
    

    编辑:

    当使用set[State]的回调版本时,事件将变为null,因为回调是异步调用的(特别是在另一个时间)。要解决此问题,您可以使用:

    e.persist();
    

    onChange 函数的顶部(但是,在这种情况下可能不是最佳的)。

    或从e.target 中获取namevalue 并将它们直接传递给回调。例如:

    const onChange = e => {
        const { name, value } = e.target;
    
        if (Object.keys(record).includes(name) {
            setRecord(prev => ({...prev, [name]: value}));
        }
        // and so on...
    }
    

    这可能是这里最合适的解决方案。

    【讨论】:

    • index.js:1406 警告:出于性能原因,此合成事件被重用。如果您看到此内容,则表示您正在访问已发布/无效合成事件上的属性 target。这设置为空。如果您必须保留原始合成事件,请使用 event.persist()。见信息。 LeadForm.js:73 未捕获的类型错误:无法在 LeadForm.js:73 在 basicStateReducer 处读取 null 的属性“名称”
    • 是的,可以通过调用e.persist() 或将namevalueonChange 顶部的事件目标中取出,然后直接使用它们而不是通过e.target。将更新答案。
    • 如何捐赠给 stack over flow
    猜你喜欢
    • 1970-01-01
    • 2020-12-05
    • 2014-03-10
    • 2020-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多