高阶组件状态正在正确更新,但接收道具的包装组件不会在状态更改时重新渲染
Posted
技术标签:
【中文标题】高阶组件状态正在正确更新,但接收道具的包装组件不会在状态更改时重新渲染【英文标题】:Higher Order Component state is updating correctly but wrapped component receiving props not re-rendering on state change 【发布时间】:2020-09-22 06:47:45 【问题描述】:我有这个 HOC,它将 dailyTime 传递到一个包装组件中,其唯一功能是显示花费的时间。它在初始渲染/页面加载时接收它的道具很好。接收 updateTime 道具并在练习完成时调用 getDailyStats 的第二个组件被正确调用,并且 getDailyStats 正在运行,并且 HOC 中的状态正在更新(渲染中的 console.log 总是在更新)但是我的包装组件是接收该更新是在状态更改时重新呈现。我想知道它是否与重组无关?无论如何,我们将不胜感激任何帮助!
const withDailyStats = WrappedComponent =>
class withDailyStats extends React.Component
constructor(props)
super(props);
this.state =
;
getDailyStats = async () =>
const authUser = this.props.authUser.uid
let userSets = await this.props.firebase.sets()
.where('userId', '==', authUser)
.get()
let data = userSets.docs.map(doc => doc.data());
let now = moment()
let pastDay = moment().startOf('day')
let pastWeek = moment().startOf('week')
let todaySets = data.filter(set =>
const setTime = moment((set.createdAt.toDate()))
return setTime >= pastDay
)
let todaysTime = todaySets.reduce((a, b) => a + (parseFloat(b['time']) || 0), 0)
todaysTime = this.msToTime(todaysTime);
this.setState(
dailyTime: todaysTime,
todaySets
)
msToTime = (s) =>
// Pad to 2 or 3 digits, default is 2
function pad(n, z)
z = z || 2;
return ('00' + n).slice(-z);
var ms = s % 1000;
s = (s - ms) / 1000;
var secs = s % 60;
s = (s - secs) / 60;
var mins = s % 60;
var hrs = (s - mins) / 60;
return pad(hrs) + ':' + pad(mins) + ':' + pad(secs)
componentDidMount()
this.getDailyStats()
render()
console.log('HOC STATE', this.state.dailyTime)
return <WrappedComponent dailyTime=this.state.dailyTime ...this.props updateTime=.
this.getDailyStats />;
;
return compose(
withFirebase,
withAuthentication,
)(withDailyStats);
export default withDailyStats;
这是未更新的包装组件。它曾经是功能性的,但我将它更改为一个类组件,只是作为一个测试。
class DailyStatModule extends React.Component
state =
componentDidMount()
console.log('daily mount', this.props.dailyTime)
render()
console.log('DSM', this.props)
return (
<DailyWrapper >
<div style=textAlign: "center">
<FontAwesomeIcon icon=faClock sz="lg" />
<div>this.props.dailyTime</div>
</div>
</DailyWrapper>
);
export default withDailyStats(DailyStatModule)
【问题讨论】:
是否有任何理由让 HOC 和组件具有相同的withDailyStats
名称?我只是想知道 compose 函数是否使用 HOC 而不是组件。您可以尝试重命名其中一个吗?
刚刚尝试使用 wtihDailyStatsWrapper 重命名包装器并导入...没有用。认为它可能有效,似乎是个好主意.... @VishalSharma
【参考方案1】:
您的 withDailyStats
hoc 正被 2 个组件使用。 getDailyStats
由 Component1
执行,它更新 withDailyStats 的状态。此更新不会传播到DailyStatModule
组件。对不起。
从设计上讲,React 是一种数据流方式。在您的情况下,您可以使用 context api 或 redux 或
另外,看看here 和here
【讨论】:
是的,我试图避免使用 redux。虽然,这一切都说得通。只会添加一个上下文提供者/消费者。【参考方案2】:根据您的代码,我假设包装的组件最初只呈现一次,因为使用了 componentDidMount?
我认为您可能想在包装的组件上尝试 componentDidUpdate 来比较 props 以进行后续更新。
这里的详细信息: https://reactjs.org/docs/react-component.html#componentdidupdate
【讨论】:
以上是关于高阶组件状态正在正确更新,但接收道具的包装组件不会在状态更改时重新渲染的主要内容,如果未能解决你的问题,请参考以下文章