背景
我正在使用一个使用ReactJS作为渲染库的Meteor应用程序.
目前,我在更新数据时重新渲染子组件时遇到问题,即使父进程正在访问更新的数据&据说把它传给了孩子.
Parent组件是一个数据表.子组件是单击编辑日期字段.
它(理论上)的工作方式:父组件将日期的现有数据作为prop传递给子组件.子组件获取现有的道具数据,处理它和它.设置一些使用它的状态,然后有两个选项:
>默认:显示数据
>如果用户点击数据字段:更改为输入&允许用户选择日期(使用react-datepicker),更改状态 – 当用户点击字段外,触发返回仅显示&将更新的数据从状态保存到数据库
我在表中每行使用子组件两次,每次使用它时,它需要访问数据库中的最新日期数据.因此,如果数据在一个字段中更改,则第二个字段应反映该更改.
问题
除非我手动刷新页面并强制子组件使用新数据进行渲染,否则第二个字段不会反映数据库中的更改.编辑的字段反映了数据的变化,因为它反映了存储在状态中的内容.
阅读完React文档之后,我确定问题是因为日期是作为一个prop进入,然后作为一个状态处理 – 并且因为该组件不会从prop更改中重新呈现.
我的问题
我该怎么做才能解决这个问题?
我对文档所做的所有阅读强烈建议远离诸如forceUpdate()和getDerivedStateFromProps()之类的东西,但结果我不确定如何通过我想要的方式传递数据.
思考?
我的守则
我已经将代码缩写了一点点&删除了特定于我的项目的变量名称,但如果它有帮助,我可以提供更多的实际名称.我认为我的问题比直接调试更具概念性.
亲
ParentComponent () {
//Date comes as a prop from database subscription
var date1 = this.props.dates.date1
var date2 = this.props.dates.date2
return(
儿童
ChildComponent() {
constructor(props) {
super(props);
this.state = {
date1: this.props.selected[0],date2: this.props.selected[1],field: false,};
}
handleDatePick() {
//Handles the event listeners for clicks in/out of the div,handles calling Meteor to update database.
}
renderDate1() {
return(
(如果这个代码/我的解释很粗糙,那是因为我还是一个相当初学者/低级别的开发人员.我没有接受过正式培训,所以我在学习一个非常困难的应用程序时正在学习.独唱开发者.这是一个很长的故事.请温柔!)
最佳答案
React文档有一个关于constructor()
最佳实践用法的部分.阅读,密切注意黄色突出显示的“注意”部分,应该说明你遇到的确切问题.
本质上,constructor()只运行一次,最常用于初始化内部/本地状态(或绑定方法).这意味着当为该子项调用constructor()时,您的子组件将使用所选prop的值设置date1和date2.无论选择的值是什么,在构造函数()被调用时将被设置为子状态,并且即使值继续更改也将保持不变.
因此,传递给子组件的所选prop的任何连续更新都不会反映在该组件的内部状态中,这意味着不会重新呈现该组件.您需要在子组件的其他位置使用React的setState()方法来正确更新该子级的状态并触发重新呈现.
使用React生命周期方法的组合来正确更新子组件是可行的方法.下面的代码片段为您提供了有关在componentDidMount()和componentDidUpdate()中实现更改的主要想法
class Child extends React.Component {
constructor(props) {
super(props);
this.state = {
date1: 0,date2: 0,};
}
/*
Any time the child mounts to the DOM,you can use the method below to set
your state using the current value of your
selected prop from the parent component...
*/
componentDidMount() {
this.setState({
date1: this.props.selected[0],date2: this.props.selected[1]
});
}
/*
When the child receives an update from its parent,in this case a new date selection,and should
re-render based on that update,use the method below
to make a comparison of your selected prop and then
call setState again...
*/
componentDidUpdate(prevProps) {
if (prevProps.selected !== this.props.selected) {
this.setState({
date1: this.props.selected[0],date2: this.props.selected[1]
});
}
}
render() {
const { date1,date2 } = this.state;
return (
由于您正在为您的孩子使用React Component模式,因此充分利用React生命周期方法将真正帮助您.我不能强烈建议您学习the React component lifecyle.当您继续使用React时,它将在此类情况下变得至关重要. componentDidMount()
和componentDidUpdate()
是个好地方.
希望这会有所帮助.让我们知道结果如何.
原文链接:https://www.f2er.com/js/429281.html