开发者问题收集

Reactjs-TypeError:无法读取 null 的属性“value”

2020-05-18
1023

我是 ReactJS 的新手,仍在练习。我的输入表单有问题,每当我输入任何键时,我总是得到 TypeError:无法读取 null 的属性“值”

这是我的代码:

import React, { useState } from 'react';

export default function FormPractice() {
const [isDefault, setIsDefault] = useState('');
const [balance, setBalance] = useState({amount: null});

return (
  <div className="input">
    <input placeholder="enter balance here" onChange={e => setBalance(form => ({...form, [e.target.value]: e.target.value}))} value={isDefault}/>
  </div>
)
}

谢谢帮助。

1个回答

React 重复使用事件 。当您使用功能更新时,在调用该函数时,事件已被清除以供重复使用。要在功能更新中使用该事件,您需要调用 e.persist() ,这会将该事件从重用池中取出并让其保留其值。

要使其保持内联,它看起来应该像这样:

onChange={e => {e.persist(); setBalance(form => ({...form, [e.target.value]: e.target.value}))}}

或者为了使其更具可读性,将其移入其自己的函数中:

const onChange = (e) => {
  e.persist();
  setBalance(form => ({...form, [e.target.value]: e.target.value}));
}

但是,最简单的可用解决方案是根本不使用功能更新。您正在替换状态值,但您没有设置从先前状态派生的任何值。因此,使用常规更新是安全的:

onChange={e => setBalance({...balance, [e.target.value]: e.target.value})}

现在事件重用不再是问题。

旁注: [e.target.value]: e.target.value 这实际上没有任何意义。您正在将一个对象键设置为与新值名称相同的值。

似乎您之前可能见过 [e.target.name]: e.target.value 并对其进行了修改。我建议使用该名称,然后为 input 提供要更新的属性的名称。

这是一个简化的示例:

const {useState, useEffect} = React;

const Example = () => {
  const [state, setState] = useState({ input1: '' });
   
  const onChange = (e) => {
    setState({[e.target.name]: e.target.value});
  }
   
   return (
    <input 
      name="input1"
      placeholder="enter balance here" 
      onChange={onChange} 
      value={state.input1}
    />
  );
}

ReactDOM.render(<Example />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Brian Thompson
2020-05-18