为了账号安全,请及时绑定邮箱和手机立即绑定

React DOM 在状态更改时不更新

React DOM 在状态更改时不更新

小怪兽爱吃肉 2022-08-18 15:43:30
我有一个 react 组件,它将接受任意数量的文件,每个文件都有自己的语言。我希望能够有一个按钮,允许用户根据需要添加任意数量的文件,每个文件都有自己的语言下拉菜单。我现在已经消除了文件上传,因为我隔离了我遇到的问题。我已经创建了相当多的类似组件,没有问题,但由于某种原因,我在使用这个组件时遇到了很大的麻烦。当我更改下拉列表中的语言时,我控制台日志状态,并看到该语言已在状态中更新,但它不会在我的映射方法中的 DOM 上更新。这是我的代码function App() {  const [files, setFiles] = useState([]);  const languages = ["English", "Spanish", "Arabic", "French"];  const handleAddFile = e => {    let newFiles = files;    newFiles.push({      content: null,      preview: null,      language: ""    });    setFiles(newFiles);  };  const changeLanguage = (event, index) => {    let newFiles = files;    newFiles[index].language = event.target.value;    setFiles(newFiles);  };  console.log(files);  return (    <div>      <p>Files</p>      <p>Upload a file for as many languages as you have</p>      {files.map((file, index) => (        <div key={index}>          <p>current language: {file.language}</p>          <select            value={file.language}            onChange={event => changeLanguage(event, index)}          >            <option value="" disabled>              Select a language            </option>            {languages.map((lang, i) => (              <option value={lang} key={i}>                {lang}              </option>            ))}          </select>        </div>      ))}      <button onClick={e => handleAddFile(e)}>+ Add File</button>    </div>  );}我还制作了一个代码和框来重现这个问题,但它实际上使事情变得更加复杂。当我在本地运行代码时,我能够很好地添加文件实例,但是select元素上的语言不会在任何实例的DOM上更新。在代码和框中,除非我在编辑器中进行编辑,否则DOM上不会更新任何内容,然后所有内容都会像我预期的那样更新,包括语言。在所有情况下,状态都是完全按照我的预期在控制台上记录的。沙盒中的组件与我本地的组件相同,尽管在本地它嵌入到另一个组件中。https://codesandbox.io/s/ed4fx?file=/src/App.js:0-1248
查看完整描述

1 回答

?
侃侃无极

TA贡献2051条经验 获得超10个赞

问题在于这两种方法和 ,您直接访问状态值文件,因此要进行更新,您需要进行复制并进行更改并设置新值。handleAddFilechangeLanguage


您需要在这两种方法中进行的更新


let newFiles = files;


let newFiles = [...files];

正如@Brian建议的那样,当您更新深嵌套值时,例如方法中的语言。您可以执行如下所示的操作,这样它就不会改变状态。changeLanguage


const changeLanguage = (event, index) => {

  let newFiles = [...files];

  newFiles[index] = { ...newFiles[index], language: event.target.value };

  setFiles(newFiles);

};

检查此工作代码和框

更好的解释在这里


查看完整回答
反对 回复 2022-08-18
  • 1 回答
  • 0 关注
  • 272 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信