我有一個關于 SolidJS 的新手問題。我有一個包含物件的陣列,例如待辦事項串列。我將其呈現為帶有輸入欄位的串列,以編輯這些物件中的屬性之一。在輸入欄位之一中鍵入時,輸入直接失去焦點。
打字時如何防止輸入失去焦點?
這是一個演示問題的 CodeSandbox 示例:https ://codesandbox.io/s/6s8y2x?file=/src/main.tsx
以下是演示該問題的源代碼:
import { render } from "solid-js/web";
import { createSignal, For } from 'solid-js'
function App() {
const [todos, setTodos] = createSignal([
{ id: 1, text: 'cleanup' },
{ id: 2, text: 'groceries' },
])
return (
<div>
<div>
<h2>Todos</h2>
<p>
Problem: whilst typing in one of the input fields, they lose focus
</p>
<For each={todos()}>
{(todo, index) => {
console.log('render', index(), todo)
return <div>
<input
value={todo.text}
onInput={event => {
setTodos(todos => {
return replace(todos, index(), {
...todo,
text: event.target.value
})
})
}}
/>
</div>
}}
</For>
Data: {JSON.stringify(todos())}
</div>
</div>
);
}
/*
* Returns a cloned array where the item at the provided index is replaced
*/
function replace<T>(array: Array<T>, index: number, newItem: T) : Array<T> {
const clone = array.slice(0)
clone[index] = newItem
return clone
}
render(() => <App />, document.getElementById("app")!);
uj5u.com熱心網友回復:
<For>components 輸入陣列的鍵項被參考。當您使用 更新 todos 中的 todo 項時replace,您正在創建一個全新的物件。Solid 然后將新物件視為完全不相關的專案,并為其創建一個新的 HTML 元素。
您可以createStore改為使用并僅更新 todo 物件的單個屬性,而不更改對它的參考。
const [todos, setTodos] = createStore([
{ id: 1, text: 'cleanup' },
{ id: 2, text: 'groceries' },
])
const updateTodo = (id, text) => {
setTodos(o => o.id === id, "text", text)
}
或使用替代控制流組件來映射輸入陣列,該組件采用顯式鍵屬性: https ://github.com/solidjs-community/solid-primitives/tree/main/packages/keyed#Key
<Key each={todos()} by="id">
...
</Key>
uj5u.com熱心網友回復:
雖然@thetarnav 解決方案有效,但我想提出我自己的解決方案。我會通過使用來解決它<Index>
import { render } from "solid-js/web";
import { createSignal, Index } from "solid-js";
/*
* Returns a cloned array where the item at the provided index is replaced
*/
function replace<T>(array: Array<T>, index: number, newItem: T): Array<T> {
const clone = array.slice(0);
clone[index] = newItem;
return clone;
}
function App() {
const [todos, setTodos] = createSignal([
{ id: 1, text: "cleanup" },
{ id: 2, text: "groceries" }
]);
return (
<div>
<div>
<h2>Todos</h2>
<p>
Problem: whilst typing in one of the input fields, they lose focus
</p>
<Index each={todos()}>
{(todo, index) => {
console.log("render", index, todo());
return (
<div>
<input
value={todo().text}
onInput={(event) => {
setTodos((todos) => {
return replace(todos, index, {
...todo(),
text: event.target.value
});
});
}}
/>
</div>
);
}}
</Index>
Dat: {JSON.stringify(todos())}
</div>
</div>
);
}
render(() => <App />, document.getElementById("app")!);
如您所見,index現在物件不再是函式/信號,而是。這允許框架替換文本框行內的值。記住它是如何作業的: For 通過參考記住你的物件。如果您的物件交換位置,則可以重復使用相同的物件。Index通過索引記住您的值。如果某個索引處的值發生變化,那么這會反映在信號中。
這個解決方案并不比另一個提出的方案或多或少正確,但我覺得這更符合,更接近 Solid 的核心。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/477486.html
上一篇:如何比較2支球隊的勝率?在C中
下一篇:組合陣列的相似元素
