increment/decrement React 应用中的按钮问题

increment/decrement button issue in react app

实际上我想按顺序显示此名称,但每当我单击递增按钮时,订单(在 useState 中)递增 1,但当我第一次单击递减按钮时,订单再次递增 1,然后小于 1 .

function func() {
  let [getVal, setVal] = useState({
    alerts: "no alerts",
    order: 0,
  });
  
  let Names = [
      "Default",
      "Evil laugh",
      "classic alarm",
      "Pause",
      "intro music",
      "Got item",
      "Old bounce",
      "bark",
      "alarm tone",
    ];

  function slider(e) {
    let { order } = getVal,
    value = e.target.id,
    total = Names.length; 
    if (value === "up" && order !== total - 1) {
      setVal((rest) => ({ ...rest, order:order + 1 })); 
    } else if (value === "down" && order !== 0) {
      setVal((rest) => ({ ...rest, order: order - 1 })); 
    }
    setVal((rest) => ({ ...rest, alerts: Names[order] }));
  }


  return (
    <>
       
        <button
          onClick={slider}
          id="up"
        >
          up
        </button>

        <p>
          {getVal.alerts}
        </p>

        <button
          onClick={slider}
          id="down"
        >down
        </button>
</>
)
}

您需要在 slider() 函数中进行以下更改。它会解决您的问题。

在 React 中更新状态是一个异步任务。你在 if 条件的内部和外部都这样做了。这就是为什么它没有在第一次点击时减少订单。

  function slider(e) {
    let { order } = getVal,
    value = e.target.id,
    total = Names.length; 

    if (value === "up" && order !== total - 1) {
      setVal((rest) => ({ ...rest, order:order + 1, alerts: Names[order + 1]})); 
    } else if (value === "down" && order !== 0) {
      setVal((rest) => ({ ...rest, order: order - 1, alerts: Names[order - 1] })); 
    }
  }

完整的 React 代码片段:

import React, { useState } from "react";

function func() {
  let [getVal, setVal] = useState({
    alerts: "no alerts",
    order: 0,
  });
  
  let Names = [
      "Default",
      "Evil laugh",
      "classic alarm",
      "Pause",
      "intro music",
      "Got item",
      "Old bounce",
      "bark",
      "alarm tone",
    ];

  function slider(e) {
    let { order } = getVal,
    value = e.target.id,
    total = Names.length; 

    if (value === "up" && order !== total - 1) {
      setVal((rest) => ({ ...rest, order:order + 1, alerts: Names[order + 1]})); 
    } else if (value === "down" && order !== 0) {
      setVal((rest) => ({ ...rest, order: order - 1, alerts: Names[order - 1] })); 
    }
  }


  return (
    <>
       
        <button
          onClick={slider}
          id="up"
        >
          up
        </button>

        <p>
          {getVal.alerts}
        </p>

        <button
          onClick={slider}
          id="down"
        >down
        </button>
</>
)
}

您的处理程序不需要那么复杂。我还建议使用 data-attributes 而不是 id。我做了一些更改:

  1. 变量名,这样它们更有意义——当你谈论数组时,indexorder 更好。

  2. 不再需要状态警报。只需将名称加载到状态中,然后让组件在当前索引处显示名称。

const { Fragment, useEffect, useState } = React;

// Pass in the names as a prop
function Example({ names }) {

  // Add the names to state, and initialise the index
  const [ state, setState ] = useState({ names, index: 0 });

  function handleClick(e) {
    
    // Get the id from the button's dataset
    const { id } = e.target.dataset;

    // Get the names, and index, from state
    const { names, index } = state;

    // Create a new index
    const newIndex = id === 'down'
      ? index - 1
      : index + 1;

    // Set a new state if the newIndex is between 0
    // and less than the names array length
    if (newIndex >= 0 && newIndex < names.length) {
      setState({ ...state, index: newIndex });
    }
  
  }

  return (
    <Fragment>
      <button data-id="down" onClick={handleClick}>Down</button>
      <p>{state.names[state.index]}</p>
      <button data-id="up" onClick={handleClick}>Up</button>
    </Fragment>
  );
};

const names=["Default","Evil laugh","classic alarm","Pause","intro music","Got item","Old bounce","bark","alarm tone"];

ReactDOM.render(
  <Example names={names} />,
  document.getElementById('react')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>

这是您方法的简化版本。


function func() {
  let [order, setOrder] = useState(0);

  let Names = [
    "Default",
    "Evil laugh",
    "classic alarm",
    "Pause",
    "intro music",
    "Got item",
    "Old bounce",
    "bark",
    "alarm tone"
  ];

  function slider(e) {
    var action = e.target.id,
        total = Names.length;

    if (action === "up" && order !== total - 1) {
      setOrder( order + 1 );
    } else if (action === "down" && order !== 0) {
      setOrder( order - 1 );
    }
  }

  return (
    <div>
      <button onClick={slider} id="up">
        up
      </button>

      <p>{Names[order]}</p>

      <button onClick={slider} id="down">
        down
      </button>
    </div>
  );
}