Javascript React Js使用onChange更新数组中的值到子组件

Javascript React Js使用onChange更新数组中的值到子组件,javascript,arrays,reactjs,components,Javascript,Arrays,Reactjs,Components,我在渲染函数中映射了一个包含开放时间的列表。我将它们映射到一个子组件。当子组件状态更改时,我希望更改父状态内每个对象的值。唯一的问题是,我的值在子组件和父状态中都不会更改。我已将onChange方法传递给每个子组件,但问题在于父状态下的onChange函数 我试图将onChange传递给我的子组件,并用[e.target.name]:e.target.value更新状态。但那没用。因此,我尝试复制arrayList并根据映射的arrayList的索引更新状态。那也没用 handleOnC

我在渲染函数中映射了一个包含开放时间的列表。我将它们映射到一个子组件。当子组件状态更改时,我希望更改父状态内每个对象的值。唯一的问题是,我的值在子组件和父状态中都不会更改。我已将onChange方法传递给每个子组件,但问题在于父状态下的onChange函数

我试图将onChange传递给我的子组件,并用[e.target.name]:e.target.value更新状态。但那没用。因此,我尝试复制arrayList并根据映射的arrayList的索引更新状态。那也没用

    handleOnChange =  (index) => {
        let newData = [...this.state.opening_hours];
        this.setState(
            newData.map((barbershop, j) => {
                if (j === index) {
                    return barbershop;
                    console.log(barbershop)
                }
            return {
                newData,
            };
        }));
        console.log(newData)
    };

    render() {
        return (
            <>
                <div className="container mb-2">
                    <h4>Opening hours </h4>
                    <Form>
                        {this.state.opening_hours.map((barbershop, index) => (
                            <Day
                                key={barbershop.id}
                                day={barbershop.day}
                                open_time={barbershop.open_time}
                                close_time={barbershop.close_time}
                                index = {index}
                                onChange={() => this.handleOnChange(index)}/>
                        ))}
                    </Form>


                    <Button onClick={this.handleSubmit} variant="primary" type="submit">
                        Update opening hours
                    </Button>
                </div>
            </>
        );
    }
}
handleOnChange=(索引)=>{
让newData=[…this.state.opening_hours];
这是我的国家(
newData.map((理发店,j)=>{
如果(j==索引){
返回理发店;
控制台日志(理发店)
}
返回{
新数据,
};
}));
console.log(newData)
};
render(){
返回(
营业时间
{this.state.opening_hours.map((理发店,索引)=>(
this.handleOnChange(index)}/>
))}
更新开放时间
);
}
}
我的子组件如下所示

class Day extends Component {

    constructor(props) {
        super(props);
        this.state = {
            day: this.props.day,
            open_time: this.props.open_time,
            close_time: this.props.close_time,
        };
        console.log(this.state)
    }

    handleChange = () => {
        this.props.onChange(this.props.index)
    }

    render() {
        return (
                <Form.Group as={Row}>
                <Form.Label column sm="3">
                    {ENUM[this.state.day]}
                </Form.Label>
                <Col sm="3">
                    <Form.Control
                        name="open_time"
                        value={this.state.open_time}
                        onChange={this.handleChange}
                        type="time"
                        min="08:00"
                        max="24:00"/>
                </Col>
                <Col sm="3">
                    <Form.Control
                        name="close_time"
                        value={this.state.close_time}
                        onChange={this.handleChange}
                        type="time"
                        min="08:00"
                        max="24:00"/>
                </Col>
            </Form.Group>
        );
    }
}

上课时间延长组件{
建造师(道具){
超级(道具);
此.state={
day:这是道具日,
开放时间:这个。道具。开放时间,
关闭时间:这个。道具。关闭时间,
};
console.log(this.state)
}
handleChange=()=>{
this.props.onChange(this.props.index)
}
render(){
返回(
{ENUM[this.state.day]}
);
}
}
编辑:


您正在传递一个调用this.handleChange(index)的函数,但您确实应该将该方法作为道具传递给
组件,并在其中调用它。您已经传入了
索引
(尽管我会使用
barbershop.id

因此,在您的父组件中,我将执行以下操作:

<Day 
  key={barbershop.id}
  day={barbershop.day}
  open_time={barbershop.open_time}
  close_time={barbershop.close_time}
  index = {barbershop.id}
  handleChange={this.handleOnChange}
/>
handleChange = (id) => {
  this.setState(() => ({
    opening_hours: this.state.opening_hours.filter((barbershop) => { 
      return barbershop.id === id;
    })
  }))
}

所以我做了一些调查,我相信问题在于你没有将数据返回给消费者

以下是我的想法,解决方案是:

import React, { Component, useState, useEffect } from "react";

class UI extends Component {
  handleOnChange = ({ index, ...newHours }) => {
    // update array item
    const opening_hours = this.state.opening_hours.map((item, i) => {
      const newData = i === index ? newHours : {};

      return {
        ...item,
        ...newData
      };
    });

    // update item in opening_hours => state
    this.setState({ opening_hours });
  };

  render() {
    return (
      <div className="container mb-2">
        <h4>Opening hours</h4>

        <Form>
          {this.state.opening_hours.map(({ id, ...barbershop }, index) => (
            <Day
              key={id}
              {...barbershop}
              {...{ index }}
              onChange={this.handleOnChange}
            />
          ))}
        </Form>

        <Button onClick={this.handleSubmit} variant="primary" type="submit">
          Update opening hours
        </Button>
      </div>
    );
  }
}

const Day = ({ day, onChange, index, ...props }) => {
  const [open_time, setOpenTime] = useState(props.open_time);
  const [close_time, setCloseTime] = useState(props.close_time);

  useEffect(() => {
    onChange({ index, open_time, close_time });
  }, [open_time, close_time, onChange, index]);

  const sharedProps = {
    type: "time",
    min: "08:00",
    max: "24:00"
  };

  return (
    <Form.Group as={Row}>
      <Form.Label column sm="3">
        {ENUM[day]}
      </Form.Label>

      <Col sm="3">
        <Form.Control
          {...sharedProps}
          name="open_time"
          value={open_time}
          onChange={({ target }) => setOpenTime(target.value)}
        />
      </Col>

      <Col sm="3">
        <Form.Control
          {...sharedProps}
          name="close_time"
          value={close_time}
          onChange={({ target }) => setCloseTime(target.value)}
        />
      </Col>
    </Form.Group>
  );
};
import React,{Component,useState,useffect}来自“React”;
类UI扩展组件{
handleOnChange=({index,…newHours})=>{
//更新数组项
const opening_hours=this.state.opening_hours.map((项目,i)=>{
const newData=i==index?newHours:{};
返回{
…项目,
…新数据
};
});
//更新处于开放时间=>状态的项目
这个.setState({营业时间});
};
render(){
返回(
营业时间
{this.state.opening_hours.map({id,…barbershop},index)=>(
))}
更新开放时间
);
}
}
常数日=({Day,onChange,index,…props})=>{
const[open_time,setOpenTime]=useState(props.open_time);
const[close_time,setCloseTime]=useState(props.close_time);
useffect(()=>{
onChange({index,open\u time,close\u time});
},[open_time,close_time,onChange,index]);
常量sharedProps={
键入:“时间”,
分钟:“08:00”,
马克斯:“24:00”
};
返回(
{ENUM[day]}
setOpenTime(target.value)}
/>
setCloseTime(target.value)}
/>
);
};

尝试此操作时,我的整个阵列将显示。怎么可能?我只剩下一个问题了。每次更改值时,它都会在数组中创建一个新对象,而不会更改数组中特定值的值。这是我当前的代码:我使用了像这样的扩展运算符,但它现在说“列表中的每个孩子都应该有一个唯一的“键”道具。”我如何解决这个问题?这就是我现在的代码:handleOnChange=(id)=>{This.setState(previousState=>({opening_hours:[…previousState.opening_hours,This.state.opening_hours.filter((barbershop)=>{return barbershop.id==id;})]}你可以这样做:
This.setState(previousState=>({…prevState,opening_hours:this.state.opening_hours.filter((barbershop)=>{return barbershop.id==id;}}))
@Jbonez87我使用了你的新解决方案,但它仍然删除了整个阵列。@TonyStark你想对这个阵列做什么?你想过滤掉所有与该id不匹配的理发店,然后只返回该理发店吗?从你的原始代码看,这就是你想做的。你能分享你的价值吗s
this.state.opening_hours
从父组件何时装载开始?当我更改某一天的open_时间和close_时间时,它每天都会更改。有时它会在另一天更改。我用console.log尝试过它,这确实是随机的。这怎么可能?你能尝试一下
I==index
是的!它终于起作用了。Could请解释它是如何工作的?以及它与我的不同之处。我真的想从我的错误中吸取教训,并感谢你对我的帮助。当然,代码背后的前提是当组件更新时你接收数据。我返回了数组项位置和所需数据的索引。映射非常简单,它在你的每个项上循环数组,如果映射为