React Js使用onChange将数组内的值更新到子组件
Posted
技术标签:
【中文标题】React Js使用onChange将数组内的值更新到子组件【英文标题】:React Js Updating a value inside a array with onChange to a child component 【发布时间】:2019-10-17 19:32:10 【问题描述】:我在渲染函数中映射了一个包含 opening_hours 的列表。我将它们映射到子组件。当子组件状态发生更改时,我想更改父状态中每个对象的值。唯一的问题是我的值在子组件和父状态中都没有改变。我已经将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>
</>
);
我的子组件是这样的
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>
);
编辑:
【问题讨论】:
【参考方案1】:您正在传递一个调用this.handleChange(index)
的函数,但您确实应该将该方法作为道具传递给您的<Day />
组件并在那里调用它。你已经传入了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
/>
然后在父组件的this.handleChange
方法中,如果您只是想为特定理发店获取this.state.opening_hours
,我会这样做:
handleChange = (id) =>
this.setState(() => (
opening_hours: this.state.opening_hours.filter((barbershop) =>
return barbershop.id === id;
)
))
【讨论】:
当我尝试这个时,我的整个数组消失了。这怎么可能? 我只剩下一个问题了。每次我更改值时,它都会在我的数组中创建一个新对象,而不会更改数组中特定值的值。这是我当前的代码:我已经像这样使用了扩展运算符,但它现在说“列表中的每个孩子都应该有一个唯一的“键”道具。”我该如何解决?这就是我现在拥有代码的方式:handleOnChange = (id) => this.setState(previousState => ( opening_hours: [...previousState.opening_hours, this.state.opening_hours.filter((barbershop) => return barbershop.id === id; ) ])) 你可以这样做:this.setState(prevState => ( ...prevState, opening_hours: this.state.opening_hours.filter((barbershop) => return barbershop.id === id; ) ))
@Jbonez87 我已经使用了你的新解决方案,但它仍然删除了整个数组。
@TonyStark 你想对这个数组做什么?您是否要过滤掉所有与该 ID 不匹配的理发店并返回该理发店?从您的原始代码来看,这就是您想要做的事情。能否分享一下父组件挂载时this.state.opening_hours
以什么值开头?【参考方案2】:
所以我做了一些调查,我认为问题在于您没有将数据返回给消费者。
这是我的想法,解决方案是:
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>
);
;
【讨论】:
当我更改某一天的 open_time 和 close_time 时,它每天都会更改。有时它会改变另一天。这真的很随机,我用 console.log 试过了。这怎么可能? 你可以试试i === index
是的!它终于奏效了。你能解释一下它是如何工作的吗?以及为什么它与我的不同。我真的很想从我的错误中吸取教训,并感谢你帮助了我。
当然,代码背后的前提是您在组件更新时接收数据。我返回了数组项位置和所需数据的索引。映射非常简单,就是遍历数组中的每个项目,如果 map() 索引与处理程序中的索引匹配,那么它会获取数据并将其传播到现有数据上,从而在不更改数组顺序的情况下更新道具。
错误在于表达式。 Is 正在评估索引是否不是处理程序索引。因此,除了我们想要的项目之外的所有其他项目都在更新。这有助于澄清事情吗?以上是关于React Js使用onChange将数组内的值更新到子组件的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 onchange javascript 对循环内的值求和
React 输入设置状态 onChange 设置多个状态属性