【问题标题】:Loop over array with map() function onClick (ReactJS)使用 map() 函数 onClick (ReactJS) 循环遍历数组
【发布时间】:2026-01-16 18:20:03
【问题描述】:

我想创建一个在用户单击“下一步”按钮时更改内容的向导。

我目前正在尝试使用 .map 函数,它可以工作,但是如何调整我的代码以循环遍历数组 onClick 中的每个步骤?

目前,我的代码仅显示 3 个单独的输入以及数组中的所有步骤,我想要做的是遍历每个步骤 onClick。

这是我的代码示例:

数组:

const wizardControls = {
    steps: [
        {
            step: 1,
            name: 'name1',
            type: 'text',
            placeholder: 'name1',
        },
        {
            step: 2,
            name: 'name2',
            type: 'text',
            placeholder: 'name2',
        },
        {
            step: 3,
            name: 'name3',
            type: 'text',
            placeholder: 'name3',
        },
    ],
};

JSX 使用 map() 函数:

    {steps.map((step, index) => (
        <div key={index}>
            <input
                value={value}
                name={step.name}
                type={step.type}
                placeholder={step.placeholder}
                onChange={onChange}
            />
        </div>
    ))}

我认为按钮需要一个处理函数来循环索引,但是我不确定如何使用 map() 函数来做到这一点。

如果 map() 函数不是最佳路径,我愿意接受更好的方法。

【问题讨论】:

  • 如果我理解正确,您只想在用户点击下一个显示索引 1 时才开始显示索引 0,等等?这可以通过useState 来保存当前要显示的索引,然后在没有地图的情况下使用索引来呈现您想要的数据。当您单击下一步时,只需增加存储在useState 中的索引。您可能需要对所选索引进行一些验证,具体取决于您打算对其进行的其他操作,以确保数组实际包含所请求的索引。
  • 是的,就是这样。我在我的问题中忘记提到的是,上面的数组已经使用useState 存储了。只是无法理解如何使用 map() 和迭代 onClick。 - 感谢您的洞察力!

标签: arrays reactjs loops


【解决方案1】:

您可以做到这一点的一种方法是根据您所处的步骤(基于索引)进行切片。

这是一个示例,说明您的代码可能会是什么样子。

const [step, setStep] = useState(1)

...

steps.slice(step - 1, step).map((step, index) => (
  ...
))

在此处查看工作示例:https://codesandbox.io/s/pensive-northcutt-el9w6

【讨论】:

  • 这是一个有趣的选择。感谢您花时间回答!
【解决方案2】:

如果您想一次显示一个步骤,请不要使用Array.map() 来渲染所有步骤。使用useState 保存当前索引(步骤),并通过索引从steps 数组中获取当前项。要跳到下一步,请将索引增加 1。

const { useState } = React;

const Demo = ({ steps }) => {
  const [index, setIndex] = useState(0);
  const [values, setValue] = useState([]);
  
  const next = () => 
    setIndex(step => step < steps.length -1 ? step + 1 : step);
  
  const onChange = e => {
    const val = e.target.value;
    
    setValue(v => {
      const state = [...v];
      
      state[index] = val;
      
      return state;
    })
  };
  
  const step = steps[index];

  return (
    <div>
        <input
            value={values[index] || ''}
            name={step.name}
            type={step.type}
            placeholder={step.placeholder}
            onChange={onChange}
        />
        
        <button onClick={next}>Next</button>
    </div>
  );
};

const wizardControls = {"steps":[{"step":1,"name":"name1","type":"text","placeholder":"name1"},{"step":2,"name":"name2","type":"text","placeholder":"name2"},{"step":3,"name":"name3","type":"text","placeholder":"name3"}]};

ReactDOM.render(
  <Demo steps={wizardControls.steps} />,
  root
);
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>

<div id="root"></div>

【讨论】:

  • 这就是我正在尝试的。 - 如果不介意的话,可以给useCallback加一些注释吗?到目前为止,我还没有使用过那个钩子,如果我继续使用你的解决方案,我需要把头绕在它周围。 - 我已经查看了documentation,但仍然想了解您是如何在此功能的上下文中使用它的。 - 提前谢谢你!
  • useCallback 在这里并不是绝对必要的。主要思想是在重新渲染组件时保留函数,因此由于属性(函数)的变化,子组件也不会被重新渲染。这是一个性能优化,这里可以跳过。
  • 谢谢。如果没有useCallback,这会是什么样子?在sn-p中,好像用了两次。 - 并不是说​​我不希望对其进行优化,但如果我只使用useState 来执行此操作,我会完全从代码中删除useCallback 吗?很抱歉有其他问题,我只是想了解这一点,以防我必须完全重构我的应用程序状态。
  • 这里其实不需要优化,只是我平时项目中的一个习惯。我会删除它,因为它会分散实际解决方案的注意力:)
  • 我真的很感激。我可能会在未来的某个日期回顾您在原始答案中使用useCallback 的方式。