Javascript 关于索引更改时如何更新数组的建议
我想更新数组元素,并使用索引引用位置。问题在于,索引在搜索名称(关键字)时会发生变化,它基本上会将名称设置为用户数组中的错误元素(因为索引是从过滤后的用户数组中获取的) 我有一个输入字段来搜索姓名Javascript 关于索引更改时如何更新数组的建议,javascript,reactjs,Javascript,Reactjs,我想更新数组元素,并使用索引引用位置。问题在于,索引在搜索名称(关键字)时会发生变化,它基本上会将名称设置为用户数组中的错误元素(因为索引是从过滤后的用户数组中获取的) 我有一个输入字段来搜索姓名 <input value={keyword} onChange={(e) => setKeyword(e.target.value)} placeholder="search"/> setKeyword(e.target.value)}占位符=“搜索”/> 然后我用每个名称渲染一
<input value={keyword} onChange={(e) => setKeyword(e.target.value)} placeholder="search"/>
setKeyword(e.target.value)}占位符=“搜索”/>
然后我用每个名称渲染一个子组件,并传递一个道具来更新名称
users
.filter((user) =>
user.toLowerCase().includes(keyword.toLowerCase())
)
.map((user, index) => (
<User
user={user}
updateName={updateName}
index={index}
key={index}
/>
))
用户
.filter((用户)=>
user.toLowerCase().includes(关键字.toLowerCase())
)
.map((用户,索引)=>(
))
我的用户组件
const User (props) => <button onClick={props.updateName(index, "some name")}>{props.user}</button>
const User(props)=>{props.User}
这个很好用。关键字更改时除外。因为users.map会改变,而且显然会改变索引。但问题是我使用索引来更新数组元素
例如,如果我搜索“Ma”关键字。2个名称匹配,因此筛选用户的索引将更改为0,1,但用户数组仍然相同
我怎样才能解决这个问题?谢谢。如果您想保留当前的数据结构,您可以放弃
过滤器
,只通过有条件地呈现用户
组件,在映射
功能中进行过滤。这样,您就不会丢失索引的记帐功能
users
.map((user, index) => (
user.toLowerCase().includes(keyword.toLowerCase()) && <User
user={user}
updateName={updateName}
index={index}
key={index}
/>
))
用户
.map((用户,索引)=>(
user.toLowerCase().includes(关键字.toLowerCase())&&
))
我建议您停止使用索引来跟踪项目在数组中的位置,因为当项目被删除或添加时,这很可能会导致问题。相反,您应该为每个项目创建一个唯一的标识符,并以这种方式跟踪它们
下面是一个例子,说明了一种方法:
函数MyComponent(){
const initialUsers=[“John”、“Marty”、“Mary”、“Johanna”]地图(
(名称,idx)=>{
返回{id:idx+1,name};
}
);
const[users,setUsers]=React.useState(initialUsers);
const[keyword,setKeyword]=React.useState(“”);
const handleOnChange=事件=>{
const{value}=event.target;
const nextUsers=initialUsers.filter(用户=>
user.name.toLowerCase().includes(值)
);
setUsers(nextUsers);
设置关键字(值);
};
返回(
搜索名称:
{users.map(user=>(
-
[{user.id}]{user.name}
))}
);
}
下面是一个工作示例,您可以对其进行测试:
希望这有帮助。导入React,{useState}来自“React”;
import React, { useState } from "react";
import "./styles.css";
export default function App() {
const names = ["John", "Marty", "Mary", "Johnna"];
// create a map of user objs to hold the position and name of each user
const mappedUsers = names.map((name, i) => {
return { position: i, name };
});
const [users, setUsers] = useState(mappedUsers);
const [keyword, setKeyword] = useState("");
const updateName = (position, name) => {
setUsers(prevUsers => {
prevUsers[position].name = name;
// return a new merged array of users
return [...prevUsers];
});
};
const User = ({ updateName, user }) => (
<div>
<button onClick={() => updateName(user.position, "someName")}>
{user.name}
</button>
</div>
);
const UserList = ({ users, keyword }) => {
return users
.filter(user => user.name.toLowerCase().includes(keyword.toLowerCase()))
.map(user => (
<User key={user.position} updateName={updateName} user={user} />
));
};
return (
<>
<input
value={keyword}
onChange={e => setKeyword(e.target.value)}
placeholder="search"
/>
<UserList users={users} keyword={keyword} />
</>
);
}
导入“/styles.css”;
导出默认函数App(){
常量名称=[“约翰”、“马蒂”、“玛丽”、“约翰娜”];
//创建用户objs的地图,以保存每个用户的位置和名称
const mappedUsers=names.map((name,i)=>{
返回{位置:i,name};
});
const[users,setUsers]=useState(mappedUsers);
const[keyword,setKeyword]=useState(“”);
const updateName=(位置、名称)=>{
setUsers(prevUsers=>{
prevUsers[position].name=name;
//返回新的合并用户数组
返回[…用户];
});
};
const User=({updateName,User})=>(
updateName(user.position,“someName”)}>
{user.name}
);
const UserList=({用户,关键字})=>{
返回用户
.filter(user=>user.name.toLowerCase().includes(关键字.toLowerCase()))
.map(用户=>(
));
};
返回(
setKeyword(e.target.value)}
占位符=“搜索”
/>
);
}
你可以使用一个对象数组[{name:“John”},…]
直接传递对象而不是索引。你应该给你的用户一个唯一的标识符,然后密钥可以是user.id
。我同意你的观点,但在这种情况下,我需要坚持使用索引。非常感谢。解决了跳过我不需要保持索引不变的内容的问题。
import React, { useState } from "react";
import "./styles.css";
export default function App() {
const names = ["John", "Marty", "Mary", "Johnna"];
// create a map of user objs to hold the position and name of each user
const mappedUsers = names.map((name, i) => {
return { position: i, name };
});
const [users, setUsers] = useState(mappedUsers);
const [keyword, setKeyword] = useState("");
const updateName = (position, name) => {
setUsers(prevUsers => {
prevUsers[position].name = name;
// return a new merged array of users
return [...prevUsers];
});
};
const User = ({ updateName, user }) => (
<div>
<button onClick={() => updateName(user.position, "someName")}>
{user.name}
</button>
</div>
);
const UserList = ({ users, keyword }) => {
return users
.filter(user => user.name.toLowerCase().includes(keyword.toLowerCase()))
.map(user => (
<User key={user.position} updateName={updateName} user={user} />
));
};
return (
<>
<input
value={keyword}
onChange={e => setKeyword(e.target.value)}
placeholder="search"
/>
<UserList users={users} keyword={keyword} />
</>
);
}