Jos*_*ong 6 arrays focus input solid-js
我有一个关于 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")!);
Run Code Online (Sandbox Code Playgroud)
更新:我已经制定了一个 CodeSandbox 示例,其中包含该问题和三个建议的解决方案(基于两个答案):https ://codesandbox.io/s/solidjs-input-field-loses-focus-when-typing-itttzy ?file=/src/App.tsx
<For>组件通过引用输入数组的键项。当您使用 更新待办事项中的待办事项时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)
}
Run Code Online (Sandbox Code Playgroud)
或者使用替代控制流组件来映射输入数组,该组件采用显式键属性: https://github.com/solidjs-community/solid-primitives/tree/main/packages/keyed#Key
<Key each={todos()} by="id">
...
</Key>
Run Code Online (Sandbox Code Playgroud)