React hooks:我在做反模式吗?组件外部功能的更新状态

时间:2019-11-26 15:54:05

标签: reactjs react-hooks

我开始使用React(仅适用于钩子),并且面临一个奇怪的问题。我正在尝试通过一个小的测试代码重现该问题,但是除了在功能完善的应用程序中,它无法实现。这使我想知道我是否做错了什么。

我有一个对象数组,声明为状态。我映射此数组以显示其内容。除了什么都没有显示(数组已填充,但什么都没有显示)。现在,如果我声明一个不相关的状态,则将其设置为一个布尔值,该值在每次更新数组时都会翻转,然后正确显示我的数组。好像在渲染阶段本身,React并未检测到阵列的更改。

几件事:

  • 该数组通过socketIO连接进行更新,我在这里使用计时器对其进行仿真
  • 我在组件函数的外部更新数组,但向更新函数提供了setter函数
  • 我还在组件函数之外创建了部分渲染字段(这没有效果,只是为了使我的完整应用程序具有可读性)

本质上,这就是我在做什么:

const updateArray = (setTestArray, setTestTag, addArray) => {
    setTestArray(prevTestArray => {
        let newTestArray = prevTestArray.map((data, index) => (data + addArray[index]))
        return newTestArray
    })
    setTestTag(prevTag => {
        return (!prevTag)
    })
}

const renderArray = (currentTestArray) => {
    return currentTestArray.map((data, index) => (
        <div>
            testArray[{index}]={data}
        </div>
    ))
}

function TestPage(props) {
    const [testArray, setTestArray] = useState([])
    const [testTag, setTestTag] = useState(false)

    useEffect(() => {
        let samples = 3
        let initArray= []
        for (let i=0; i<samples;i++) initArray[i] = Math.random()
        setTestArray(initArray)
        // In real code: setup socket here...
        setInterval(() => {
            let addArray= []
            for (let i=0; i<samples;i++) addArray[i] = Math.random()
            updateArray(setTestArray, setTestTag, addArray)
        }, 1000)        
        return (() => {
            // In real code, disconnect socket here...
        })
    }, []);

    return (
        <Paper>
            Array content:
            {renderArray(testArray)}
            <br/>
            Tag: {(testTag)? 'true' : 'false'}
        </Paper>
    )
}

这很好用。但是,在我完整的应用程序中,如果我注释掉所有与“ testTag”有关的内容,那么我的数组内容将永远不会显示。 testArray的内容符合预期,可以很好地更新,但是将调试器放置在map部分中会显示该数组为空。

因此我的问题:

  • 我的updateArray函数不是个好主意吗?从我的阅读中,我的prevTestArray输入将始终反映最新的状态值,并且setTestArray永远都不应更改...这是我看到的处理套接字连接生成的异步调用的唯一方法,而无需在其中放置“ testArray” useEffect依赖关系(从而避免连续连接/断开套接字?)
  • 在renderArray中的组件外部渲染不会影响我的测试(如果我将代码移入组件内部,则结果相同),但是这有问题吗?

作为一个副要说明,我的数组的内容实际上是真正的应用程序(对象数组)更复杂,我尝试将其放置在此测试代码中,它也可以正常工作...

谢谢!


编辑:请注意,在useEffect中移动updateArray似乎是推荐的模式。我在完整的应用程序中做到了这一点。钩子linter不会抱怨缺少任何依赖项,但这在我的完整应用程序中仍然无法正常工作。

但是问题仍然是我在这里做的事是否错:我知道这违反了指导方针,因为它阻止了短绒棉衫的工作,但是在我看来,这仍然会起作用,以前的状态可以在设置器功能中默认访问。


编辑#2:对我感到羞耻……我的真实应用程序代码中存在一个愚蠢的错误,等效于updateArray在某个位置具有浅数组副本,而不是深副本。 为什么要添加翻转标签使其起作用,这超出了我的范围(知道确实可以正确显示和更新数据),但是摆脱此错误就可以解决所有问题。

我将继续讨论这个问题,因为问题仍然存在:将状态更新和部分呈现置于组件外部是一个功能性问题,或者只是可能依赖于隐藏依赖项的某些问题(防止react hooks linter做它的工作),因此仅仅是不好的做法?

事实是,组件函数之外的两个函数现在都可以正常工作,这基于我从钩子上了解的内容。

0 个答案:

没有答案