React Native:更新上下文抛出 "Cannot update during an existing state transition"
React Native : update context throw "Cannot update during an existing state transition"
我有一个 React 本机应用程序,我正在尝试在自定义上下文中更新日期。
主题背景
export const ThemeContext = React.createContext({
theme: 'dark',
toggleTheme: () => { },
date: new Date(),
setDate: (date: Date) => { }
});
Basic context with the date and the function to update it
App.tsx
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
theme: 'dark',
date: new Date()
};
}
render() {
const { theme, date } = this.state;
const currentTheme = themes[theme];
const toggleTheme = () => {
const nextTheme = theme === 'light' ? 'dark' : 'light';
this.setState({ theme: nextTheme });
};
const setDate = (date: Date) => {
// ERROR is raised HERE
this.setState({date: date});
}
return (
<>
<IconRegistry icons={EvaIconsPack} />
<ThemeContext.Provider value={{ theme, toggleTheme, date, setDate }}>
...
</ThemeContext.Provider>
</>
);
}
}
I simply hava a state with a Date and create a setDate function. I wrapped my app into the context provider.
选择器
class PickerContent extends React.Component<{}, ContentState> {
static contextType = ThemeContext;
constructor(props: {} | Readonly<{}>) {
super(props);
let currentMode = 'date';
let show = false;
if (Platform.OS === 'ios') {
currentMode = 'datetime';
show = true;
}
this.state = {
date: new Date(),
mode: currentMode,
show: show
};
}
setMode(currentMode: string) {
this.setState({ mode: currentMode, show: true });
};
onChange(_event: any, selectedDate: Date) {
const currentDate = selectedDate || this.state.date;
// I update the context here
this.context.setDate(currentDate);
this.setState({date: currentDate, show: Platform.OS === 'ios'})
}
render() {
const {show, date, mode } = this.state;
const color = 'dark';
return (
<>
...
{show && <DateTimePicker
...
onChange={(event, selectedDate) => this.onChange(event, selectedDate)}>
</DateTimePicker>}</>
)
}
}
I use the lib 'DateTimePicker' to choose a date and bind the onChange to update the context. This picker is on a modal.
所以当DateTimePicker的onChange
函数被触发时出现警告。错误在 App.tsx
的 setState
(in setDate)
Warning: Cannot update during an existing state transition (such as within 'render'). Render methods should be a pure function of props and state.
你知道如何纠正这个错误吗?
编辑:
我使用的是 UI Kitten 库中的模态组件。我切换到 react native Modal,错误消失了。错误似乎来自图书馆。抱歉
提前感谢您的帮助,
西尔万
如果您正在使用 class 组件,您可以将上下文更新 fn 移动到 componentDidUpdate
中。你只需比较你的状态,如果你的状态发生了变化,你就用新值更新你的上下文。
大致如下:
componentDidUpdate(prevProps, prevState) {
if (prevState.date !== this.state.date) {
this.context.setDate(this.state.date);
}
}
onChange(_event: any, selectedDate: Date) {
const currentDate = selectedDate || this.state.date;
this.setState({date: currentDate, show: Platform.OS === 'ios'})
}
这样您就不会在渲染期间更新上下文。
如果您将此组件重构为功能性组件,您将能够使用 useEffect
执行相同的操作。
我编辑了我的问题。错误最终似乎来自使用的库 (ui kitten)。
我有一个 React 本机应用程序,我正在尝试在自定义上下文中更新日期。
主题背景
export const ThemeContext = React.createContext({
theme: 'dark',
toggleTheme: () => { },
date: new Date(),
setDate: (date: Date) => { }
});
Basic context with the date and the function to update it
App.tsx
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
theme: 'dark',
date: new Date()
};
}
render() {
const { theme, date } = this.state;
const currentTheme = themes[theme];
const toggleTheme = () => {
const nextTheme = theme === 'light' ? 'dark' : 'light';
this.setState({ theme: nextTheme });
};
const setDate = (date: Date) => {
// ERROR is raised HERE
this.setState({date: date});
}
return (
<>
<IconRegistry icons={EvaIconsPack} />
<ThemeContext.Provider value={{ theme, toggleTheme, date, setDate }}>
...
</ThemeContext.Provider>
</>
);
}
}
I simply hava a state with a Date and create a setDate function. I wrapped my app into the context provider.
选择器
class PickerContent extends React.Component<{}, ContentState> {
static contextType = ThemeContext;
constructor(props: {} | Readonly<{}>) {
super(props);
let currentMode = 'date';
let show = false;
if (Platform.OS === 'ios') {
currentMode = 'datetime';
show = true;
}
this.state = {
date: new Date(),
mode: currentMode,
show: show
};
}
setMode(currentMode: string) {
this.setState({ mode: currentMode, show: true });
};
onChange(_event: any, selectedDate: Date) {
const currentDate = selectedDate || this.state.date;
// I update the context here
this.context.setDate(currentDate);
this.setState({date: currentDate, show: Platform.OS === 'ios'})
}
render() {
const {show, date, mode } = this.state;
const color = 'dark';
return (
<>
...
{show && <DateTimePicker
...
onChange={(event, selectedDate) => this.onChange(event, selectedDate)}>
</DateTimePicker>}</>
)
}
}
I use the lib 'DateTimePicker' to choose a date and bind the onChange to update the context. This picker is on a modal.
所以当DateTimePicker的onChange
函数被触发时出现警告。错误在 App.tsx
的 setState
(in setDate)
Warning: Cannot update during an existing state transition (such as within 'render'). Render methods should be a pure function of props and state.
你知道如何纠正这个错误吗?
编辑:
我使用的是 UI Kitten 库中的模态组件。我切换到 react native Modal,错误消失了。错误似乎来自图书馆。抱歉
提前感谢您的帮助, 西尔万
如果您正在使用 class 组件,您可以将上下文更新 fn 移动到 componentDidUpdate
中。你只需比较你的状态,如果你的状态发生了变化,你就用新值更新你的上下文。
大致如下:
componentDidUpdate(prevProps, prevState) {
if (prevState.date !== this.state.date) {
this.context.setDate(this.state.date);
}
}
onChange(_event: any, selectedDate: Date) {
const currentDate = selectedDate || this.state.date;
this.setState({date: currentDate, show: Platform.OS === 'ios'})
}
这样您就不会在渲染期间更新上下文。
如果您将此组件重构为功能性组件,您将能够使用 useEffect
执行相同的操作。
我编辑了我的问题。错误最终似乎来自使用的库 (ui kitten)。