通过单击将元素的位置更改为顶部或底部

Change position of element to top or botton with clicks

我正在练习 React,我的任务是构建一个界面,其中一个按钮可以添加元素,另一个按钮可以删除元素,两个其他按钮可以像这样逐步向上或向下移动每个元素:

我已经能够让按钮添加和删除元素,但是改变元素的位置让我有些头疼。下面是我的代码:

const [inputList, setInputList] = useState([{ inputBox: '' }]);
  const handleInputChange = (e, index) => {
    const { name, value } = e.target;
    const list = [...inputList];
    list[index][name] = value;
    setInputList(list);
  };

  const handleRemoveClick = (index) => {
    const list = [...inputList];
    list.splice(index, 1);
    setInputList(list);
  };

  const handleAddClick = () => {
    setInputList([...inputList, { inputBox: '' }]);
  };

  const upPosition = () => {
    console.log('up');
  };

  const downPosition = () => {
    console.log('down');
  };

  return (
    <div>
      <h3>Add Elements</h3>
      <button onClick={handleAddClick}>+</button>
      {inputList.map((x, i) => {
        return (
          <div className='box inputBox' key={i}>
            <input
              name='inputBox'
              value={x.inputBox}
              onChange={(e) => handleInputChange(e, i)}
            />
            <button onClick={() => upPosition()}>
              <i className='fas fa-long-arrow-alt-up'></i>
            </button>
            <button onClick={() => downPosition()}>
              <i className='fas fa-long-arrow-alt-down'></i>
            </button>
            <button className='mr10' onClick={() => handleRemoveClick(i)}>
              <i className='fas fa-times'></i>
            </button>
          </div>
        );
      })}
    </div>
  );

您可以在这里使用splice

除了移动之外,您还必须处理两种情况,如果索引为 0 则不能上升,如果索引为 inputList.length - 1 则不能下降

注意:为了处理这两种情况,我禁用了按钮,因为让最终用户知道此按钮已禁用会更有意义,因此您可以'不涨不跌。

现场演示

const upPosition = ( index ) => {
    const copy = { ...inputList[index] };
    setInputList( ( oldState ) => {
        const newState = oldState.filter( ( o, i ) => i !== index );
        newState.splice( index - 1, 0, copy );
        return newState;
    } )
};

const downPosition = (index) => {
    const copy = { ...inputList[index] };
    setInputList( ( oldState ) => {
        const newState = oldState.filter( ( o, i ) => i !== index );
        newState.splice( index + 1, 0, copy );
        return newState;
    } )
};

你应该使用 splice 方法,它也可以进行插入

  const upPosition = (indexToMove) => {
    if (indexToMove === 0) return;
    const list = [...inputList];
    const itemToMove = list.splice(indexToMove, 1)[0];
    list.splice(indexToMove-1, 0, itemToMove)
    setInputList(list)
  };

  const downPosition = (indexToMove) => {
    if (indexToMove === inputList.length - 1) return;
    const list = [...inputList];
    const itemToMove = list.splice(indexToMove, 1)[0];
    list.splice(indexToMove+1, 0, itemToMove)
    setInputList(list)
  };

我认为你可以通过解构来实现:

const [inputList, setInputList] = useState([{ inputBox: '' }]);
  const handleInputChange = (e, index) => {
    const { name, value } = e.target;
    const list = [...inputList];
    list[index][name] = value;
    setInputList(list);
  };

  const handleRemoveClick = (index) => {
    const list = [...inputList];
    list.splice(index, 1);
    setInputList(list);
  };

  const handleAddClick = () => {
    setInputList([...inputList, { inputBox: '' }]);
  };

  const upPosition = (i) => {
    if (i > 0) {
      const temp = [...inputList];
      [temp[i], temp[i - 1]] = [temp[i - 1], temp[i]];
      setInputList(temp);
    }
  };

  const downPosition = (i) => {
    if (i < inputList.length - 1) {
      const temp = [...inputList];
      [temp[i], temp[i + 1]] = [temp[i + 1], temp[i]];
      setInputList(temp);
    }
  };

  return (
    <div>
      <h3>Add Elements</h3>
      <button onClick={handleAddClick}>+</button>
      {inputList.map((x, i) => {
        return (
          <div className="box inputBox" key={i}>
            <input
              name="inputBox"
              value={x.inputBox}
              onChange={(e) => handleInputChange(e, i)}
            />
            <button onClick={(e) => upPosition(i)}>
              <i className="fas fa-long-arrow-alt-up"></i>
            </button>
            <button onClick={() => downPosition(i)}>
              <i className="fas fa-long-arrow-alt-down"></i>
            </button>
            <button className="mr10" onClick={() => handleRemoveClick(i)}>
              <i className="fas fa-times"></i>
            </button>
          </div>
        );
      })}
    </div>
  );