首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用React组织/管理多个模态的“正确”方式

使用React组织/管理多个模态的“正确”方式
EN

Stack Overflow用户
提问于 2021-05-14 04:34:52
回答 1查看 50关注 0票数 1

我正在自学React,并一直在构建一个简单的预算系统来做到这一点。我正在使用React-Bootstrap进行设计,并构建了几个不同的模态来处理我的应用程序中的某些功能。

这个应用运行得很好,但是作为一个开发者,我觉得在我的代码设计方面,事情可能会变得更加紧张。

其中一个可以设计得更好的地方是我如何处理多个模态。正如你所看到的,我目前有4个通道,所有这些通道都被传递了各种道具(也被传递到BudgetContainer中)。其中一些功能(如"setOpenModal")是必要的,因为我需要能够控制从应用程序中的不同位置打开哪个模式。

然而,这种设计导致必须在我的应用程序中来回传递大量的道具,以便将所有数据/函数呈现在我需要的位置。经过一些研究,我发现这就是所谓的“道具钻探”。

我还研究了一些其他方法,例如某种全局状态管理方法(如Redux),但这些方法似乎都是非常笨拙的解决方案。

我还考虑将情态函数的位置移动到触发它们显示的相同组件上,然而,我最终得到的是散布在整个应用程序中的随机情态函数,而不是在一个区域中。

这里有没有什么我忽略的设计模式?我只是个反应新手?我觉得模态在web开发中是一个足够常见的特性,以至于一个解决方案肯定已经存在了。

代码语言:javascript
复制
import React, { useState } from 'react'
import { Row, Col } from 'react-bootstrap-v5'
import { useAsync } from 'react-async'

import budgetApi from '@/api/budgetApi.js'
import { transactionDefault } from '@/objectDefaults/transaction.js'
import BudgetContainer from './components/BudgetContainer.js'
import Cashflow from './components/Cashflow.js'
import UnbudgetedTransactions from './components/UnbudgetedTransactions.js'

import BudgetModal from '@/common/modals/BudgetModal'
import DeleteBudgetModal from '@/common/modals/DeleteBudgetModal'
import TransactionDetailModal from '@/common/modals/TransactionDetailModal'
import TransactionSplitModal from '@/common/modals/TransactionSplitModal'

function BudgetContent() {
    const [activeBudget, setActiveBudget] = useState({})
    const [activeTransaction, setActiveTransaction] = useState(transactionDefault)
    const [activeDate, setActiveDate] = useState(new Date())
    const [openModal, setOpenModal] = useState('')

    // Retrieve the budgeting data
    const { data, error, isPending, run } = useAsync({ 
        promiseFn: budgetApi.getPromise,
        deferFn: budgetApi.getDefer,
        watch: activeDate,
        onResolve: (resolvedData) => {
            // Update the activeBudget's data
            let freshActiveBudget = resolvedData.data.budgeted_transactions.filter(
                freshBudget => freshBudget.id == activeBudget.id
            )
            setActiveBudget(freshActiveBudget[0] ?? {})
        },
        // PHP's Carbon library can easily parse ISO dates
        period: activeDate.toISOString()
    })

    return (
        <div>
            <Row>
                <Col md={7}>
                    <BudgetContainer
                        budgets={data && data.data.budgeted_transactions}
                        activeDate={activeDate}
                        setActiveDate={setActiveDate}
                        isPending={isPending}
                        activeBudget={activeBudget}
                        setActiveBudget={setActiveBudget}
                        setActiveTransaction={setActiveTransaction}
                        setOpenModal={setOpenModal}
                    />
                </Col>
                <Col md={5}>
                    <Row>
                        <Col>
                            <Cashflow />
                        </Col>
                    </Row>
                    <Row className="pt-2">
                        <Col>
                            <UnbudgetedTransactions
                                transactions={data && data.data.unbudgeted_transactions}
                                setOpenModal={setOpenModal}
                                setActiveTransaction={setActiveTransaction} 
                            />
                        </Col>
                    </Row>
                </Col>
            </Row>

            {<TransactionDetailModal
                show={openModal == 'transaction_detail'}
                setOpenModal={setOpenModal}
                activeTransaction={activeTransaction}
                refreshBudgets={run}
                budgets={data && data.data.budgeted_transactions}
            />
            <TransactionSplitModal
                show={openModal == 'transaction_split'}
                setOpenModal={setOpenModal}
                activeTransaction={activeTransaction} 
            />
            <BudgetModal
                show={openModal == 'create_budget'}
                setOpenModal={setOpenModal}
                refreshBudgets={run}
                activeBudget={activeBudget}
            />
            <DeleteBudgetModal
                show={openModal == 'delete_budget'}
                setOpenModal={setOpenModal}
                refreshBudgets={run}
                activeBudget={activeBudget}
                setActiveBudget={setActiveBudget}
            />}
        </div>
    )
}

export default BudgetContent
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-05-20 02:18:05

最后,我选择使用React的上下文API来在元素之间共享通道所需的信息,并避免进行适当的钻探。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67525910

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档