Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/447.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.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 如何在React钩子中的对象数组中更新状态onchange_Javascript_Reactjs_React Hooks - Fatal编程技术网

Javascript 如何在React钩子中的对象数组中更新状态onchange

Javascript 如何在React钩子中的对象数组中更新状态onchange,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我检索了使用useState存储在对象数组中的数据,然后将数据输出到表单字段中。现在我希望能够在键入时更新字段(状态) 我似乎有人更新数组中属性的状态的例子,但从来没有更新过对象数组中的状态,所以我不知道怎么做。我已经将对象的索引传递给回调函数,但我不知道如何使用它更新状态 // sample datas structure const datas = [ { id: 1, name: 'john', gender: 'm' }

我检索了使用useState存储在对象数组中的数据,然后将数据输出到表单字段中。现在我希望能够在键入时更新字段(状态)

我似乎有人更新数组中属性的状态的例子,但从来没有更新过对象数组中的状态,所以我不知道怎么做。我已经将对象的索引传递给回调函数,但我不知道如何使用它更新状态


// sample datas structure
const datas = [
    {
      id:   1,
      name: 'john',
      gender: 'm'
    }
    {
      id:   2,
      name: 'mary',
      gender: 'f'
    }
]

const [datas, setDatas] = useState([]);

const updateFieldChanged = index => e => {

    console.log('index: ' + index);
    console.log('property name: '+ e.target.name);

        setData() // ??
}

return (
    <React.Fragment>
        { datas.map( (data, index) => {
              <li key={data.name}>
                <input type="text" name="name" value={data.name} onChange={updateFieldChanged(index)}  />
              </li>
          })
        }
    </React.Fragment>
)


//样本数据结构
常数数据=[
{
id:1,
姓名:'约翰',
性别:'m'
}
{
id:2,
姓名:'玛丽',
性别:“f”
}
]
const[datas,setDatas]=useState([]);
常量updateFieldChanged=索引=>e=>{
console.log('索引:'+索引);
log('property name:'+e.target.name);
setData()/??
}
返回(
{datas.map((数据,索引)=>{
  • }) } )
    以下是您的操作方法:

    //示例数据结构
    /*常数数据=[
    {
    id:1,
    姓名:'约翰',
    性别:'m'
    }
    {
    id:2,
    姓名:'玛丽',
    性别:“f”
    }
    ]*///确保在useState调用中设置默认值(我已经修复了它)
    const[datas,setDatas]=useState([
    {
    id:1,
    姓名:'约翰',
    性别:'m'
    }
    {
    id:2,
    姓名:'玛丽',
    性别:“f”
    }
    ]);
    常量updateFieldChanged=索引=>e=>{
    console.log('索引:'+索引);
    log('property name:'+e.target.name);
    让newArr=[…datas];//复制旧数据数组
    newArr[index]=e.target.value;//将e.target.value替换为您想要更改的内容
    setDatas(newArr);/??
    }
    返回(
    {datas.map((数据,索引)=>{
    
  • }) } )
    您可以通过将旧数组映射到新数组,并将您要更改的内容替换为一个更新的项目来实现这一点,而无需改变

    setDatas(
        datas.map(item => 
            item.id === index 
            ? {...item, someProp : "changed"} 
            : item 
    ))
    
    我就是这么做的:

    const [datas, setDatas] = useState([
      {
        id: 1,
        name: "john",
        gender: "m",
      },
      {
        id: 2,
        name: "mary",
        gender: "f",
      },
    ]);
    
    const updateFieldChanged = (name, index) => (event) => {
      let newArr = datas.map((item, i) => {
        if (index == i) {
          return { ...item, [name]: event.target.value };
        } else {
          return item;
        }
      });
      setDatas(newArr);
    };
    
    return (
      <React.Fragment>
        {datas.map((data, index) => {
          <li key={data.name}>
            <input
              type="text"
              name="name"
              value={data.name}
              onChange={updateFieldChanged("name", index)}
            />
          </li>;
          <li key={data.gender}>
            <input
              type="text"
              name="gender"
              value={data.gender}
              onChange={updateFieldChanged("gender", index)}
            />
          </li>;
        })}
      </React.Fragment>
    );
    
    const[datas,setDatas]=useState([
    {
    id:1,
    姓名:“约翰”,
    性别:“m”,
    },
    {
    id:2,
    姓名:“玛丽”,
    性别:“f”,
    },
    ]);
    const updateFieldChanged=(名称、索引)=>(事件)=>{
    让newArr=datas.map((项目,i)=>{
    如果(索引==i){
    返回{…项,[名称]:event.target.value};
    }否则{
    退货项目;
    }
    });
    setDatas(newArr);
    };
    返回(
    {datas.map((数据,索引)=>{
    
  • ; })} );
    您甚至不需要使用索引(如果需要,键除外)也不需要复制旧的数据数组,如果您希望updateFieldChanged不内联,甚至可以内联执行,或者只将数据作为参数传递。这样做的速度非常快:

      const initial_data = [
        {
          id: 1,
          name: "john",
          gender: "m",
        },
        {
          id: 2,
          name: "mary",
          gender: "f",
        },
      ];
    
      const [datas, setDatas] = useState(initial_data);
    
      return (
        <div>
          {datas.map((data, index) => (
            <li key={index}>
              <input
                type="text"
                value={data.name}
                onChange={(e) => {
                  data.name = e.target.value;
                  setDatas([...datas]);
                }}
              />
            </li>
          ))}
        </div>
      );
    };
    
    const初始数据=[
    {
    id:1,
    姓名:“约翰”,
    性别:“m”,
    },
    {
    id:2,
    姓名:“玛丽”,
    性别:“f”,
    },
    ];
    const[datas,setDatas]=useState(初始数据);
    返回(
    {datas.map((数据,索引)=>(
    
  • { data.name=e.target.value; setDatas([…datas]); }} />
  • ))} ); };
    以@Steffan为基础,以如下方式使用:

    const [arr,arrSet] = useState(array_value);
    ...
    let newArr = [...arr];
      arr.map((data,index) => {
        newArr[index].somename= new_value;
      });
    arrSet(newArr);
    
    使用useEffect检查新的arr值

    setDatas(datas=>({
       ...datas,
       [index]: e.target.value
    }))
    

    索引是目标位置,e.target.value是新值

    感谢它的作用。我可以针对对象中的任何特定属性名称,如
    let propertyName=e.target.name
    newArr[index][propertyName]=e.target.value。但是在输入一个字母后,它没有聚焦在文本字段上,我必须再次单击该字段才能输入另一个字母。这很奇怪。我在JSFIDLE上做了一个修改,对我来说效果很好:好吧,我发现是
  • 标记中的键导致了它,因为它与输入字段共享相同的值,所以当该值更改时,整个
  • 也会刷新。设置
    key={index}
    修复了它。这会改变当前状态。Spread运算符只做浅拷贝。@vinayr在这种情况下,不需要深度拷贝。我的
    索引
    指的是数组中对象的索引,而不是对象的属性
    id
    ,就像它要去的地方,但它确实需要一些解释。对我来说,这不太管用。我必须使用:
    setUsers(users.map(usr=>usr.subjectId===updateuser.subjectId?{……updateuser}:usr))
    在我的例子中,subject是我列表中唯一的键。本质上,我映射列表并返回列表中的原始对象,除非id与我要更新的id匹配。在这种情况下,我将返回一个新对象,其中包含我更新对象的所有属性。上帝保佑。。。。。。