每个都具有重复元素的嵌套组件

问题描述 投票:0回答:1

我正在开发一种动态表单,人们可以在其中创建调查问题。

主窗体允许添加问题,每个问题可以添加1:N条件和答案。

主模板如下所示:

import React, { useState } from "react";
import Question from 'components/templates/question';
import { Button, Form } from 'react-bootstrap';

const Templates = () => {
  const [questions, setQuestions] = useState([Question()]);
 
  const increase = () => {
    setQuestions([...questions, Question()]);
  };

  return (
    <form>
      {questions.map((component, index) => (
        <React.Fragment key={index}>
          { component }
        </React.Fragment>
      ))}
      <Button variant='success' onClick={increase}> + </Button>
    </form>
  );
};

包含可递增、可重复条件的问题如下所示:

import React, { useState } from "react";
import { Button, Card, Form } from 'react-bootstrap';
import Condition from './condition';

const Question = () => {
    const [conditions, setConditions] = useState([Condition()]);

    const increaseC = () => {
        setConditions([...conditions, Condition()]);
    };

  return (
    <Card className="mb-4">
        <Card.Body>
            <Form.Group className="mb-3" controlId="questionTitle">
                <Form.Label>Question Title</Form.Label>
                <Form.Control type="text" placeholder="What is a simple name for this data point?" />
            </Form.Group>
            <Form.Group className="mb-3" controlId="questionDescription">
                <Form.Label>Question Description</Form.Label>
                <Form.Control type="text" placeholder="What are you looking for?" />
            </Form.Group>
            <h5 class="card-title">Conditions</h5>
            <h6 class="card-subtitle text-muted">Are there conditions for when this text is displayed?</h6>
            {conditions.map((component, index) => (
                <React.Fragment key={index}>
                { component }
                </React.Fragment>
            ))}
            <br />
            <Button variant='outline-success' size="sm" onClick={increaseC}>+</Button>
        </Card.Body>
    </Card>
  );
}

export default Question;

正如你所想,这是行不通的。我见过在组件之间传递参数,但我一生都无法弄清楚如何拥有映射组件集合的多个状态。

reactjs
1个回答
0
投票

您可以采取多种方法。主要思想是存储条件数据而不是组件本身。您应该使您的

<Condition />
成为受控组件,它将数据作为道具,并提供
onChange
回调,以在编辑后更新条件。

interface ConditionData {
  // condition-related data
}
// store a list of conditions' data
const [conditions, setConditions] = useState<ConditionData>([]);

const increaseC = () => {
    setConditions([...conditions, { ...initialConditionData }]);
};

const onConditionChange = useCallback((data: ConditionData, index: number) => {
    // Update condition that changed on the given index
    setConditions(conditions => 
      conditions.map((condition, conditionIndex) =>
        conditionIndex === index ? data : condition
      )
    );
}, []);

return (
  ...
  {conditions.map((data, index) => (
    <Condition
      key={index}
      data={data}
      onChange={(data) => onConditionChange(data, index)} 
    />
  ))}
  ...
)

理想情况下,您应该为新条件生成唯一的 ID,以便在删除条件后,未更改条件的键不会更改。这是对上面代码的简单修改。

interface ConditionData {
  id: number;
  // condition-related data
}

function* createConditionGenerator() {
  let id = 0;
  while (true) {
    yield { ...initialConditionData, id }
    id++;
  }
}

const generateNewCondition = createConditionGenerator();

const [conditions, setConditions] = useState<ConditionData>([generateNewCondition.next().value]);


const increaseC = () => {
  setConditions([...conditions, ]);
};

const onConditionChange = useCallback((data: ConditionData) => {
    // Update condition that changed on the given index
    setConditions(conditions => 
      conditions.map((condition) =>
        condition.id === data.id ? data : condition
      )
    );
}, []);

return (
  ...
  {conditions.map((data) => (
    <Condition
      key={data.id}
      data={data}
      onChange={onConditionChange} 
    />
  ))}
  ...
)
© www.soinside.com 2019 - 2024. All rights reserved.