我有一个React测试应用程序,使用Zustand作为商店。该应用程序只显示一个输入字段,但每次字段的值被更新,整个应用程序被刷新。我一定是做了一些愚蠢的商店,但似乎没有找到什么。任何帮助将不胜感激。
import React, { useEffect } from 'react'
import { create } from 'zustand'
import { v4 as uuidv4 } from 'uuid';
const store = create((set, get) => ({
currentPage: { blocks: [] },
blocksForCurrentPage: [],
findBlockById: blockId => get().blocksForCurrentPage.find(block => block.blockId === blockId),
_addDummyBlockAtEndOfPage: _ => {
const newDummyBlock = ({blockId: uuidv4(), content:'', type:undefined, isDummy: true})
set(state => ({ blocksForCurrentPage: [...state.blocksForCurrentPage, newDummyBlock] }))
set(state => ({ currentPage: { ...state.currentPage, blocks: [...state.currentPage.blocks, newDummyBlock.blockId] } }))
},
initCurrentPage: _ => {
const blocks = get().currentPage?.blocks
const lastBlockId = blocks.length > 0 ? blocks[blocks.length - 1] : undefined
if (lastBlockId === undefined || !get().findBlockById(lastBlockId)?.isDummy) get()._addDummyBlockAtEndOfPage()
},
updateBlock: ({ blockId, type, content }) => {
//update the block content
const index = get().blocksForCurrentPage.findIndex(block => block.blockId === blockId)
if (index < 0) return
set(state => {
const block = state.blocksForCurrentPage[index]
const newArray = [...state.blocksForCurrentPage]
newArray.splice(index, 1, { ...block, type, content, isDummy: false })
return {blocksForCurrentPage: newArray}
})
},
}))
function App () {
const { currentPage, initCurrentPage, updateBlock } = store((state) => ({
currentPage: state.currentPage,
initCurrentPage: state.initCurrentPage,
updateBlock: state.updateBlock,
}))
console.log('Redraw app')
useEffect(() => {
console.log('in use event')
initCurrentPage()
}, [currentPage])
const onChange = (t, blockId) => {
updateBlock({ blockId, content: t.target?.value })
}
return <>{currentPage?.blocks?.map((blockId) => <input key={blockId}
onChange={t => onChange(t, blockId)}/>)}</>
}
export default App;
输出打印一次“使用中事件”,预计只会出现一次,效果很好。但是,每次我在输入框处于焦点状态时按下一个键,“重绘应用程序”就会打印出来。
现在,每当输入的值发生变化时,我都会更新blocksForCurrentPage数组中的一个项,但正如您所看到的,渲染只依赖于currentPage,而不依赖于blocksForCurrentPage。
对于那些愿意在这里提供帮助的人来说,是package.json文件
{
"name": "webclient",
"version": "0.1.0",
"private": true,
"dependencies": {
"immer": "^9.0.19",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"uuid": "^9.0.0",
"zustand": "^4.3.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
2条答案
按热度按时间yhuiod9q1#
算了吧,刚搬到MOBX 1000000x比zustand更容易理解的作品就像一个魅力
s5a0g9ez2#
为了将来的参考,我相信你需要传入'shallow'。你正在重新渲染一个没有稳定引用的对象,所以每次渲染都是新的。