首页 > 解决方案 > React:我可以在基于 props 的可重用组件中创建动态数量的状态吗?

问题描述

我正在做一个附带项目,我有条件地想根据用户的回答向用户提出一系列问题。我这个命令:

步骤 1. 我询问用户他们是否有特定的帐户/会员资格步骤 2. 如果有,我会显示一系列问题,如果他们在该帐户/会员资格中有评分步骤 3. 如果有,我会显示一个输入,询问他们特定的评分

为了实现这一点,我有一个父组件来询问初始问题(步骤 1)。对于步骤 1(步骤 2)中的每个问题,我有一个可重用的子组件有条件地显示,并且每个问题都来自道具。然后,我有第二个可重用组件,由步骤 2 有条件地显示,它要求评分,其措辞也来自 props(步骤 3)

我的挑战是,在第 2 步中,我希望我的组件有 n 个状态,其中 n 是我传递给它的数组的大小,以便我可以跟踪是否应该为第 3 步显示每个问题。一种方法来做到这一点,还是有更优雅的解决方案?理论上我可以在这个组件树的顶部对每个状态进行硬编码,然后将状态作为道具传递,但我认为有一种更优雅的方式来做到这一点。

我的代码如下:

初始形式(步骤 1)

export default function ChessForm() {
    const [FIDE, setFide] = useState(false)
    const [USCF, setUSCF] = useState(false)
    const [Chesscom, setChesscom] = useState(false)
    const [LiChess, setLiChess] = useState(false)


    return (
        <Form>
            <p>Please fill out the below form</p>
            <Form.Group>
                <Form.Label className='mx-2'>Do you have a FIDE membership?</Form.Label>
                <Form.Check inline label='Yes' value={true} name='FIDE' type='radio' className = 'mx-2' name='FIDE'  onClick = {()=>{setFide(true)}}/>
                <Form.Check inline label='No' value ={false} name='FIDE'  type='radio' className = 'mx-2' defaultChecked  onClick={()=>{setFide(false)}}  />
            </Form.Group>

            {FIDE && <MembershipForm inputs={['standard', 'rapid', 'blitz']} name='FIDE'/>}

            <Form.Group>
                <Form.Label className = 'mx-2'>Do you have a USCF membership?</Form.Label>
                <Form.Check inline label='Yes' name='USCF' type='radio' className = 'mx-2'  onClick={()=>{setUSCF(true)}} />
                <Form.Check inline label='No' name='USCF'  type='radio' className = 'mx-2' defaultChecked onClick={()=>{setUSCF(false)}} />
            </Form.Group>

            {USCF && <MembershipForm inputs={['regular', 'quick', 'blitz']} name='USCF'/>}

            <Form.Group>
                <Form.Label className = 'mx-2'>Do you have a Chess.com account?</Form.Label>
                <Form.Check inline label='Yes' name='Chesscom' type='radio' className = 'mx-2' onClick={()=>{setChesscom(true)}}/>
                <Form.Check inline label='No' name='Chesscom'  type='radio' className = 'mx-2' defaultChecked onClick={()=>{setChesscom(false)}}/>
            </Form.Group>

            {Chesscom && <MembershipForm inputs={['bullet', 'blitz', 'rapid', 'Daily', 'puzzle']} name='USCF'/>}

            <Form.Group>
                <Form.Label className = 'mx-2'>Do you have a LiChess account?</Form.Label>
                <Form.Check inline label='Yes' name='LiChess' type='radio' className = 'mx-2' onClick={()=>{setLiChess(true)}} />
                <Form.Check inline label='No' name='LiChess'  type='radio' className = 'mx-2' defaultChecked onClick={()=>{setLiChess(false)}} />
            </Form.Group>

            {LiChess && <MembershipForm inputs={['bullet', 'blitz', 'rapid', 'Classical', 'Correspondence' , 'puzzle']} name='USCF'/>}
        </Form>
    )
}

第 2 步表单(可重用组件) *注意我目前有一个标准、快速和闪电战的状态。这是问题的症结所在。我想根据我传递给这个组件的道具来获得动态的状态。

import React, {useState} from 'react'
import {Form} from 'react-bootstrap'
import RatingInput from './RatingInput'

export default function MembershipForm({inputs, name}) {
    const [standard, setStandard] = useState(false)
    const [rapid, setRapid] = useState(false)
    const [blitz, setBlitz] = useState(false)

    const questions=inputs.map(input => {
            return (
                <>
                    <Form.Group>
                        <Form.Label className='mx-2'>Do you have a {name} {input} Rating?</Form.Label>
                        <Form.Check inline label='Yes' value={true} name={name+input} type='radio' className = 'mx-2' onClick = {()=>{setStandard(true)}}/>
                        <Form.Check inline label='No' value ={false} name={name+input}  type='radio' className = 'mx-2' defaultChecked onClick = {()=>{setStandard(false)}}  />
                    </Form.Group>
                    {standard && <RatingInput name={input}/>}
                </>
            )
        })
    return (
        <div className='ml-3'>
            {questions}
        </div>
    )
}

第 3 步:最后这是我要根据上述组件的状态有条件地显示的第三个组件

import React from 'react'
import {Form, Container, Row, Col} from 'react-bootstrap'


export default function RatingInput({name}) {
    return (
        <Container>
            <Row>
            
                <Col><Form.Label inline>What is your {name} rating?</Form.Label></Col>
                <Col><Form.Control type='number' min ={500} max ={3200} className='w-50 h-75' /></Col>
            </Row>
            <Form.Group>
            
        </Form.Group>
        </Container>
        
    )
}

标签: javascriptreactjs

解决方案


推荐阅读