Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/461.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 关于索引更改时如何更新数组的建议_Javascript_Reactjs - Fatal编程技术网

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} />
    </>
  );
}