You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React点击按钮重复生成组件:三个实现函数哪个更接近解决方案?

How to Dynamically Add Custom Components on Button Click in React

Hey Janakanty, let's break down your current code and fix this dynamic component addition issue—you're already thinking in the right direction, just missing some key React patterns!

What's Wrong With Your Current Functions

Let's go through each one to understand why they aren't working as expected:

  • Adding function:
    • You've defined components as an object ({ button : Button }), but map() only works on arrays.
    • The function doesn't return any JSX, and there's no state to track how many components should be rendered—so even if it did work, nothing would show up.
  • AddQ function:
    • This uses raw DOM manipulation (document.createElement, appendChild), which is an anti-pattern in React. React relies on its virtual DOM to sync state and UI, so directly modifying the DOM will break this sync and cause hard-to-debug issues later.
    • The counter variable is declared inside the function, so it resets to 0 every time you click the button—you'll always get "przykładowy tekst 1" instead of incrementing numbers.
  • AddQuestion function:
    • ReactDOM.render() replaces the entire contents of the target element (#ankieta) every time it's called, which is why you only ever see one button. It doesn't append new components—it overwrites what's already there.

The Correct React Approach: Use State to Track Components

React is declarative, so we use state to track how many (or which) components we want to render, then let React handle updating the UI automatically. Here's a working solution tailored to your questionnaire use case:

Step 1: Define Your Custom Question Component

First, let's create a reusable component for your questionnaire input (replace this with your actual Button or input component):

// Your custom question component (adjust this to match your needs)
const QuestionComponent = ({ questionId }) => (
  <div className="question-container">
    <h4>Question {questionId}</h4>
    <input type="text" placeholder="Enter your question here" />
    {/* Add any other inputs/options you need for the question */}
  </div>
);

Step 2: Build the Main Component with State

We'll use useState to keep track of our list of questions. Each time the button is clicked, we add a new entry to the state array, and React will render all components in the array:

import { useState } from 'react';

const QuestionnaireBuilder = () => {
  // State to track our list of questions (we'll use unique IDs for each)
  const [questions, setQuestions] = useState([]);

  // Function to add a new question when the button is clicked
  const handleAddQuestion = () => {
    // Generate a unique ID for the new question (using array length + 1 for simplicity)
    const newQuestionId = questions.length + 1;
    // Update state by spreading the existing questions and adding the new ID
    setQuestions(prevQuestions => [...prevQuestions, newQuestionId]);
  };

  return (
    <div className="questionnaire-builder">
      {/* Button to trigger adding a new question */}
      <button onClick={handleAddQuestion} style={{ padding: '8px 16px', marginBottom: '16px' }}>
        Add New Question
      </button>

      {/* Container where questions will be rendered */}
      <div id="ankieta">
        {/* Map over the questions array to render each QuestionComponent */}
        {questions.map(questionId => (
          <QuestionComponent key={questionId} questionId={questionId} />
        ))}
      </div>
    </div>
  );
};

export default QuestionnaireBuilder;

Key Concepts Explained

  • State Management: The questions state array tracks all the questions we want to render. When we call setQuestions, React re-renders the component with the updated array.
  • Declarative Rendering: Instead of manually manipulating the DOM, we tell React "here's the list of questions, render each one as a QuestionComponent". React takes care of updating the UI efficiently.
  • Unique Keys: We use questionId as the key prop for each component—this helps React identify which components have changed, been added, or removed, ensuring smooth re-renders.

If you need to store more data for each question (like default text, answer type, etc.), you can modify the state to store objects instead of just IDs. For example:

// Adding a question with more data
setQuestions(prev => [...prev, { id: newQuestionId, type: 'text', label: '' }]);

Then you can pass that data to your QuestionComponent to pre-fill or customize it!

内容的提问来源于stack exchange,提问作者Janakanty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 09:02:41