0

我在我的 React 应用程序中使用钩子来处理状态。

我的应用程序具有notes与类别相关联的categoryId.

NoteList通过安装组件来显示特定类别中的注释。

<NoteList categoryObj={categoryObj} />

功能NoteList组件

export const NoteList = (props) => {
  const [notesToRender, setNotesToRender] = useState(props.notes)
  
  useEffect(() => {
    console.log('I fired!', props.categoryObj.id, props.notes)
    setNotesToRender(props.notes)
  }, [props.categoryObj.id]);

  //...
  
  return (
    notesToRender.map((note) => {
      return <NoteListItem key={note.id} {...note}/>
    }
  )
}

const mapStateToProps = (state) => {
  notes: getNotesForCategory(state) // Selector that returns notes where note.id === props.categoryObj.id
}

export default connect(mapStateToProps)(NoteList)

选择器

export const getNotesForCategory = createSelector(
  [getNotes, getcategoryId],
  (notes, categoryId) => {
    const categoryNotes = notes.filter(note => note.id === categoryId)
    console.log('categoryNotes ', categoryNotes) // This log shows the correct notes
    return categoryNotes 
  }
)

我创建notesToRender是因为有时我需要在渲染注释之前过滤它们(此处未显示该代码)。

在类别(更新)之间切换时props.categoryObj.id,注释无法正确显示。

加载应用程序时,状态是正确的,但在类别之间切换时,useEffect 会以某种方式导致状态“落后一步”。

  1. A 类 - 初始负载 - 正常
  2. 切换到“B 类”——console.log() 显示正确的 categoryId,但来自 A 类的注释
  3. 切换到“A 类”——console.log() 显示正确的 categoryId,但来自 B 类的注释
  4. 切换到“B 类”——console.log() 显示正确的 categoryId,但来自 A 类的注释

... 等等

选择器的控制台日志显示了正确的注释。问题可能是在useEffect之后mapStateToProps触发?如何确保在 useEffect之前触发而不导致不必要的重新渲染 === 仅在更改时?mapStateToPropsprops.categoryObj.id

亲切的问候/K

4

1 回答 1

0

对我来说,解决方案似乎是将 useEffect() 依赖项从 更改props.categoryObj.idprops.notes. 我现在唯一的障碍是如何比较 useEffect() 依赖项中的两个对象数组。

到目前为止我测试过的东西是:

  1. props.notes.length -> 有效但不可靠 - 原因很明显:)
  2. ...props.notes --> 如果数组不为空但可能会导致严重的性能问题?

我在这里发布了一个新问题 --> React useEffect() :最有效的方法来比较两个对象数组是否相等

于 2020-12-04T07:59:56.073 回答