LoginSignup
yuta1414win
@yuta1414win

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

削除メソッドを完成させたい

解決したいこと

deleteを活用して要素を削除したいのですが、エラーが出てしまう状況です。

発生している問題・エラー

import { useState } from "react";

const App = () => {
  // 作成したtodoを入れておくためのstate"配列"を活用する
  const [todos, setTodos] = useState([]);
  // フォームに入力された値をtodoに登録するまでに入れておくためのstate"文字列"
  const [tmpTodo, setTmpTodo] = useState("");

  const addTodo = () => {
    setTodos([...todos, tmpTodo]);
    setTmpTodo("");
  }

  const deleteTodo = (index) => {
    //deleteTodo(todos[index]);
    //todos.splice(0,1);
  }

  return (
    <>
      <h1>Todo App</h1>
      <div className="form">
        <input
          type="text"
          name="todo"
          ///id="message"を追加する
          user_text="todos"
          // formの入力値をtmpTodoで持っておく
          onChange={e => setTmpTodo(e.target.value)}
          value={tmpTodo}
        />
        <button onClick={addTodo}>追加</button>
      </div>
      <ul>
      {todos.map((todo, index) => <li key={index}>{todo}
          <button onClick={() => deleteTodo(index)}>×</button></li>
          )}
      </ul>
      <style>{`
        h1 {
          text-align: center;
        }
        .form {
          display: flex;
          justify-content: center;
        }
        ul {
          width: 200px;
          margin: 10px auto;
        }
      `}</style>
    </>
  );
};
export default App;

例)

Unhandled Runtime Error
RangeError: Maximum call stack size exceeded
14〜17行目でエラーが出ています。

または、問題・エラーが起きている画像をここにドラッグアンドドロップ

例)

 const deleteTodo = (index) => {
    deleteTodo(todos[index]);
    todos.splice(0,1);
  }
0

1Answer

そのエラーは,deleteTodoの中でdeleteTodoを呼び出しており,再帰が起きていることに起因するものです.再帰関数deleteTodoの終了条件がないため無限に再帰呼び出しが行われ,RangeError: Maximum call stack size exceededというようなエラーが出てきます.関数呼び出し(call)にはstackを使うので,その最大サイズを超えた(exceeded)ということですね,再帰関数で実装するのは意図していなさそうなことから,再帰でなくするためにdeleteTodo関数の宣言時か,もしくはdeleteTodo(todos[index]);で書いた関数名のどちらかを変更することになると思います.

または

deleteを活用して要素を削除したい

という要件ですが下部にあるspliceで十分そうです.deleteTodo関数の処理を

const deleteTodo = (index) => 
    todos.splice(index,1);
}

にすると良いのではないでしょうか.deleteを使うならdelete todos[index];ですね.
ただ,JSのドキュメントでも言われている通り,deleteしても配列のサイズは元のサイズのままでindex番目だけが空になりますので,どのみち消した分の要素を詰めるためにspliceを使うことになりそうです.

0

Your answer might help someone💌