【发布时间】:2020-04-02 23:37:13
【问题描述】:
我在将上下文添加到使用提供程序的组件的状态时遇到问题。
下面的代码是一个名为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>
)
}
}
【问题讨论】:
-
上下文提供者如何提供上下文?
-
我已经为提供者添加了相关代码。谢谢
-
上下文是否传递给消费者?
console.log(context)之前返回<Typography ...
标签: javascript reactjs react-context