LoginSignup
2
0

More than 1 year has passed since last update.

の続きです。

イベントハンドリング

function handleSubmit(e) {
  e.preventDefault();
  alert('Hello, world!');
}

<form onSubmit={handleSubmit}>

Reactの例では、上記のようにhandleSubmit関数でe.preventDefaultを実行し、alert関数を発火させていますが、qwikではこのようにEventで発火させる処理として、直接e.preventDefaultを入れて実行することができません。

以下のように設定します。
Qwikでは非同期のために、イベントハンドラがダウンロードされていません。なので代わりにpreventdefault:{eventName}属性が存在します。

<form 
  preventdefault:submit
  onSubmit$={() => {
    alert("Hello, world")
  }
}>

状態の更新

状態の更新には useStoreを使用します。
useStore は以下のようにObjectを初期値として取ります。

const state = useStore({ count: 0 });

入力したタスクをSubmitした際にalert関数で表示させるようにしてみます。

useStoreでstateを作成し、Formコンポーネントにpropsとして渡します。

src/routes/index.tsx
import { component$, useStore } from '@builder.io/qwik';

export default component$(() => {
 const nameStore = useStore({
    name: "",
 });

~~~~
 <Form nameStore={nameStore} />

そこからonChangeでnameを更新し、onSubmitで表示させます。

src/components/form/index.tsx
import { component$ } from "@builder.io/qwik";


type Form = {
  nameStore: any 
}

export default component$(({ nameStore }: Form) => {
  return (
    <form 
      preventdefault:submit
      onSubmit$={() => {
        alert(`追加したタスクは、${nameStore.name}です。`)
      }
    }>
      <h2 className="label-wrapper">
        <label for="new-todo-input" className="label__lg">
          What needs to be done?
        </label>
      </h2>
      <input
        type="text"
        id="new-todo-input"
        className="input input__lg"
        name="text"
        autoComplete="off"
        onChange$={(e) => {
          nameStore.name = e.target.value
        }}
      />
      <button type="submit" className="btn btn__primary btn__lg">
        Add
      </button>
    </form>
  )
})

以下のように表示できることが確認できると思います。
スクリーンショット 2022-12-03 23.25.28.png

タスク管理用のstate作成

タスク管理用のstateを作成し、それをmockしているデータと置き換えます。

src/routes/index.tsx
 export default component$(() => {
-  const DATA = [
-    { id: "todo-0", name: "Eat", completed: true },
-    { id: "todo-1", name: "Sleep", completed: false },
-    { id: "todo-2", name: "Repeat", completed: false },
-  ];
+  const taskStore = useStore({
+    name: "",
+    tasks: []
+  });
-    { id: "todo-2", name: "Repeat", completed: false },
-  ];
+  const taskStore = useStore({
+    name: "",
+    tasks: []
+  });
 
-  const taskList = DATA.map((task) => (
-    <Todo id={task.id} name={task.name} completed={task.completed} />
+  const taskList = taskStore.tasks.map((task) => (
+    <Todo id={task.id} name={task.name} completed={task.completed} key={task.id} />
   ));
 
   return (
     <div className="todoapp stack-large">
       <h1>TodoMatic</h1>
-      <Form />
+      <Form taskStore={taskStore} />
       <div className="filters btn-group 
diff/src/components/index.tsx
 import { component$ } from "@builder.io/qwik";
+import { nanoid } from "nanoid";
 
 
-export default component$(() => {
+type Form = {
+  taskStore: any
+}
+
+export default component$(({ taskStore }: Form) => {
   return (
-    <form>
+    <form
+      preventdefault:submit
+      onSubmit$={() => {
+        const newTask = { id: `todo-${nanoid()}`, name: taskStore.name, completed: false };
+        taskStore.tasks = [...taskStore.tasks, newTask]
+        taskStore.name = ""
+      }
+    }>
       <h2 className="label-wrapper">
         <label for="new-todo-input" className="label__lg">
           What needs to be done?
@@ -15,6 +27,10 @@ export default component$(() => {
         className="input input__lg"
         name="text"
         autoComplete="off"
+        value={taskStore.name}
+        onChange$={(e) => {
+          taskStore.name = e.target.value
+        }}
       />
       <button type="submit" className="btn btn__primary btn__lg">
         Add

ここまで実装するとタスクに自由に追加するところまでできます。

スクリーンショット 2022-12-03 23.34.24.png

タスク数を表示

タスク数の表示が固定で 3 tasks remaining になっているのでついでにtaskListをカウントして表示させます。

src/routes/index.tsx
+  const headingText = `${taskList.length} tasks remaining`;
+
   return (
     <div className="todoapp stack-large">
       <h1>TodoMatic</h1>
@@ -25,7 +27,7 @@ export default component$(() => {
         <FilterButton category='Completed' />
       </div>
       <h2 id="list-heading">
-        3 tasks remaining
+        {headingText}
       </h2>
       <ul
         role="list"

スクリーンショット 2022-12-03 23.39.23.png

明日も引き続きやっていきます。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0