我无法将上下文添加到正在消耗提供程序的组件状态中。
下面的代码是一个名为Timer
的子组件,父组件包装在ReadingSessionProvider
中。
我将duration
存储为session
对象的属性,该对象存储在父级状态中。例如,它以"00:10:00"
的形式存储在字符串中。我可以在父级中访问此值,而不会出现任何问题。
我想将其拆分并在状态中将分钟和小时作为单独的变量存储,以便将其用作倒数计时器,但是,如果没有某些特定事件,似乎无法访问上下文的值,在这种情况下,onClick
。
如果我尝试在此之前设置状态,则context.state.session.duration
值是不确定的。
在下面的代码中,倒数计时器使用默认值,但是当我单击按钮时,startSession
正确设置了状态,但是计时器不再起作用。例如,如果此持续时间值为"00:10:00"
,它将保持不变。
为此,我尝试了其他各种尝试,甚至尝试询问是否将值作为道具here传递,但没有解决方案。
我不确定我的处理方法是否有什么问题,或者我试图完成的事情是不可能的。
任何帮助将不胜感激。谢谢!
class Timer extends React.Component {
state = {
'minutes': 3,
'seconds': 59,
'timerText': 'Time Remaining: '
}
startCountdown() {
this.myInterval = setInterval(() => {
const { seconds, minutes } = this.state;
if (seconds > 0) {
this.setState(({ seconds }) => ({
seconds: seconds - 1
}))
}
if (seconds === 0) {
if (minutes === 0) {
clearInterval(this.myInterval)
} else {
this.setState(({ minutes }) => ({
minutes: minutes - 1,
seconds: 59
}))
}
}
}, 1000);
}
componentDidMount() {
console.log(this.context)
this.startCountdown();
}
startSession(duration) {
this.setState({'minutes': duration.split(":")[1]});
this.setState({'seconds': duration.split(":")[2]});
this.startCountdown()
}
render() {
return (
<ReadingSessionContext.Consumer>
{(context) => {
return (
<Typography component="h1" variant="h5">
{ this.state.minutes }:{ this.state.seconds < 10 ? `${ this.state.seconds }` : this.state.seconds }
<Button onClick={() => this.startSession(context.state.session.duration)}>Start Session</Button>
</Typography>
)
}}
</ReadingSessionContext.Consumer>
)
}
}
export default function ReadingSessionPage() {
return (
<ReadingSessionProvider>
<Container component="main" maxWidth="lg">
<NavBar />
<CssBaseline />
<Grid container>
<ReadingSessionHeader />
</Grid>
</Container>
</ReadingSessionProvider>
)
}
function ReadingSessionHeader() {
return (
...
<Timer />
...
)
}
和提供者(出于可读性而被截断)
export default class ReadingSessionProvider extends React.Component {
/**
* Set the initial state of the `ReadingSessionProvider`
* @param {*} props
*/
state = {
"translationUrl": process.env.REACT_APP_BACKEND_URL + "translate/",
"readingSessionUrl": process.env.REACT_APP_BACKEND_URL + "reading-sessions/",
"session": {},
"book": {},
"translations": [],
"serverPage": 1,
"clientPage": 0,
"limit": 10,
"totalResults": 0,
"sessionId": 0,
"headers": {
"Content-type": "application/json",
"Authorization": "Token " + localStorage.getItem("token"),
}
}
/**
* After the component mounts, call the `getReadingSession` method
* and update the state with response
*/
async componentDidMount() {
let data = await this.getReadingSession();
this.setState({"session": data.data});
this.setState({"book": data.data.library_item.book});
await this.getTranslations()
}
...
render() {
return (
<ReadingSessionContext.Provider value={{
state: this.state,
getTranslations: this.getTranslations,
submitText: this.submitText,
handleChangePage: this.handleChangePage,
setSessionId: this.setSessionId,
makeUrl: this.makeUrl
}}>
{this.props.children}
</ReadingSessionContext.Provider>
)
}
}
答案 0 :(得分:0)
componentDidUpdate(prevProps, prevState, snapShot) {
If(prevState !== This.state){
this.startCountdown()
}
}
答案 1 :(得分:0)
在您的构造函数中,如果有必要,您需要将this.startSession
绑定到this
。
因此,您需要在构造函数中包含this.startSession = this.startSession.bind(this);
。
constructor(props) {
super(props);
this.state = {put your state here};
this.startSession = this.startSession.bind(this);
}
我认为正在发生的事情是该函数未绑定到this
,所以当您说this.Anything
时,它正在失去作用域,因此您的状态实际上并未被更新