【问题标题】:React useEffect only works if I make a change to the code once the page is openReact useEffect 仅在页面打开后我对代码进行更改时才有效
【发布时间】:2021-09-02 20:30:45
【问题描述】:

我在 React 中遇到问题,我在组件中用于我的 useEffect 的代码可以工作,但只有如果我手动更改代码(甚至不是实质性的,它加载组件后,可以小到添加或删除 console.log)。 Here's a link 到屏幕录制所发生的事情。

我正在使用Material-UI Autocomplete 组件来创建一个列表,但是当我使用该组件加载页面时,好像useEffect 不会真正启动,直到我对代码进行某种更改之后 组件加载(同样:即使是像注释掉或添加 console.log 这样的小东西也可以)。一旦我做出改变,列表就会出现。但如果我离开页面或重新加载,我又回到了第 1 格。

同样,当我尝试在列表中选择一个选项时,它看起来好像在我更改代码之前它不起作用。只有这样我对列表所做的选择更改才会出现。

这是我为该组件准备的代码:

import React, { useState, useEffect } from 'react'
import { makeStyles } from '@material-ui/core/styles'
import Checkbox from '@material-ui/core/Checkbox'
import TextField from '@material-ui/core/TextField'
import Autocomplete from '@material-ui/lab/Autocomplete'
import Typography from '@material-ui/core/Typography'

import CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank'
import CheckBoxIcon from '@material-ui/icons/CheckBox'

const icon = <CheckBoxOutlineBlankIcon fontSize='small' />
const checkedIcon = <CheckBoxIcon fontSize='small' />

const useStyles = makeStyles((theme) => ({
  root: {
    margin: 'auto'
  },
  paper: {
    width: 250,
    height: 230,
    overflow: 'auto',
    backgroundColor: '#bdbdbd'
  },
  button: {
    margin: theme.spacing(0.5, 0)
  },
  checkbox: {
    color: '#FFF342'
  },
  textfield: {
    backgroundColor: '#bdbdbd'
  }
}))

const WordSelect = ({ newListState, setNewListState }) => {
// const WordSelect = ({ newListState, setNewListState }) => {
  const classes = useStyles()

  const [wordsText, setWordsText] = useState({
    wordOptions: []
  })

  useEffect(() => {
    const wordsText = []

    newListState.words.map(x => {
      wordsText.push(x.text)
    })

    // console.log(wordsText)

    setWordsText({ ...wordsText, wordOptions: wordsText })
  }, []) // eslint-disable-line react-hooks/exhaustive-deps


  return (
    <>
      <Autocomplete
        multiple
        id='checkboxes-tags-demo'
        disableCloseOnSelect
        value={newListState.selected}
        options={wordsText.wordOptions}
        getOptionLabel={(option) => option}
        getOptionSelected={(option, value) => option === value}
        onChange={(event, newValue) => {
          newListState.selected = newValue
        }}
        renderOption={(option, { selected }) => (
          <>
            <Checkbox
              className={classes.checkbox}
              icon={icon}
              checkedIcon={checkedIcon}
              style={{ marginRight: 8 }}
              checked={selected}
            />
            <Typography className={classes.checkbox}>
              {option}
            </Typography>
          </>
        )}
        style={{ width: 500 }}
        renderInput={(params) => (
          <TextField {...params} className={classes.textfield} variant='outlined' placeholder='Select Words' />
        )}
      />
    </>
  )
}

export default WordSelect

我真的不确定发生了什么。似乎代码必须是正确的,因为我为使其显示所做的更改类型应该对页面上呈现的内容没有影响,但是为什么它不会从一开始就呈现呢?任何提示表示赞赏。

【问题讨论】:

  • 这可能是竞争条件吗? newListState 是否总是在第一次渲染时定义?

标签: reactjs material-ui


【解决方案1】:

您尚未将 newListState 添加到您的 useEffect 依赖数组中。因此,useEffect 仅在组件的第一次渲染时运行。当您更改代码时,实时重新加载会重新加载组件并运行 useEffect 挂钩。

试试这个:

useEffect(() => { const wordsText = []

newListState.words.map(x => {
  wordsText.push(x.text)
})

// console.log(wordsText)

setWordsText({ ...wordsText, wordOptions: wordsText })

}, [setWordsText, newListState])

你真的不应该使用' // eslint-disable-line react-hooks/exhaustive-deps',因为它有助于捕捉这些问题。它还可以帮助您捕获由于过时的数据或函数而导致的一些令人讨厌的错误。

【讨论】:

  • 谢谢!这有助于解决问题的第一部分。单词列表现在出现在自动完成下拉列表中。尽管在我更新代码之前它仍然没有显示对列表的任何更改。编辑(不小心按回车键):我从来不知道 useEffect 末尾的方括号是干什么用的。我在编码方面非常陌生,并且知道足以让自己陷入困境。哈哈。当我用谷歌搜索我收到的错误消息时,我刚刚发现的 eslint 位作为解决方案。
  • 尝试阅读 React 文档以更好地了解 useEffect 之类的钩子是如何工作的。 reactjs.org/docs/getting-started.html#learn-react
  • 谢谢。我会检查一下。作为记录,我发现了第二部分的问题,它没有更新所选数据。当我设置 newValue 时,我没有使用正确的格式。我正在使用注释掉的行,但它上面的行是我应该这样做的。 ` onChange={(event, newValue) => { setNewListState({ ...newListState, selected: newValue }) // newListState.selected = newValue }} `
猜你喜欢
  • 2020-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-23
  • 2023-01-09
  • 2014-05-14
  • 1970-01-01
相关资源
最近更新 更多