高阶组件状态正在正确更新,但包装组件接收道具不会在状态更改时重新渲染
Higher Order Component state is updating correctly but wrapped component receiving props not re-rendering on state change
我有这个 HOC,它将 dailyTime 传递到一个包装组件中,它的唯一功能是显示花费的时间。它在初始 render/page 加载时接收到它的道具。接收 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 组件只是为了测试。
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)
您的 withDailyStats
hoc 正在被 2 个组件使用。 getDailyStats
由更新 withDailyStats 状态的 say Component1
执行。此更新不会传播到 DailyStatModule
组件。对不起。
根据设计,React 是一种数据流方式。在您的情况下,您可以使用 context api or redux 或
另外,看看here and
根据您的代码,我假设包装组件最初只渲染一次,因为使用了 componentDidMount?
我想你可能想在包装组件上尝试 componentDidUpdate 来比较 props 以进行后续更新。
详情在这里:
https://reactjs.org/docs/react-component.html#componentdidupdate
我有这个 HOC,它将 dailyTime 传递到一个包装组件中,它的唯一功能是显示花费的时间。它在初始 render/page 加载时接收到它的道具。接收 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 组件只是为了测试。
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)
您的 withDailyStats
hoc 正在被 2 个组件使用。 getDailyStats
由更新 withDailyStats 状态的 say Component1
执行。此更新不会传播到 DailyStatModule
组件。对不起。
根据设计,React 是一种数据流方式。在您的情况下,您可以使用 context api or redux 或
另外,看看here and
根据您的代码,我假设包装组件最初只渲染一次,因为使用了 componentDidMount?
我想你可能想在包装组件上尝试 componentDidUpdate 来比较 props 以进行后续更新。
详情在这里: https://reactjs.org/docs/react-component.html#componentdidupdate