#react-native #expo #react-context #react-native-ui-kitten
#react-native #expo #реагировать-контекст #react-native-ui-kitten
Вопрос:
У меня есть приложение react native, и я пытаюсь обновить дату в пользовательском контексте.
Тематический текст
export const ThemeContext = React.createContext({
theme: 'dark',
toggleTheme: () => { },
date: new Date(),
setDate: (date: Date) => { }
});
Базовый контекст с датой и функцией для ее обновления
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>
</>
);
}
}
Я просто задаю состояние с датой и создаю функцию setDate. Я включил свое приложение в контекстный провайдер.
Средство выбора
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 amp;amp; <DateTimePicker
...
onChange={(event, selectedDate) => this.onChange(event, selectedDate)}>
</DateTimePicker>}</>
)
}
}
Я использую библиотеку ‘DateTimePicker’, чтобы выбрать дату и привязать onChange для обновления контекста. Этот сборщик находится на модальном.
Таким образом, предупреждение появляется, когда onChange
запускается функция DateTimePicker . Ошибка находится в setState
of App.tsx
(в setDate)
Warning: Cannot update during an existing state transition (such as within 'render'). Render methods should be a pure function of props and state.
Знаете ли вы, как исправить эту ошибку?
Редактировать :
Я использовал модальный компонент из библиотеки пользовательского интерфейса Kitten. Я переключаюсь на модальный режим react native, и ошибка исчезла. Похоже, что ошибка исходит из библиотеки. извините
заранее благодарю вас за помощь, Сильвен
Комментарии:
1. Есть какие-нибудь новости по этому поводу?
2. @Konstantin Я, я отредактировал свой вопрос, ошибка, наконец, кажется, исходит из библиотеки, используемой для модального компонента.
Ответ №1:
Если вы используете компонент класса, что вы можете сделать, так это переместить контекстное обновление 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
.
Комментарии:
1. Я, спасибо за ваш ответ. Я пытался сделать то, что вы сказали, но у меня та же ошибка. Ошибка, которая возникает внутри компонента приложения, а не средства выбора. Поэтому я думаю, что ошибка связана с классом приложения
2. Насколько я понимаю, вы указали на строку
setDate
внутри вашего средства выбора. Я не могу знать, какая строка вызывает у вас проблему, поэтому, пожалуйста, соответствующим образом обновите свой вопрос.3. В конце своего вопроса я сказал: «Итак, предупреждение появляется, когда запускается функция onChange DateTimePicker. Ошибка находится в setState App.tsx (в setDate) «. разве это не ясно?
4. Я обновляю код, чтобы увидеть, какая именно строка вызвала ошибку
5. Я снова пересмотрел ваш код, почему у вас есть fns внутри рендеринга? Пожалуйста, преобразуйте их в методы (удалите
consts
, вы используете класс, а не функциональный компонент), переместите их за пределы рендеринга, передайте их с помощьюthis
в ваш контекст и, пожалуйста, сообщите мне результат объединения этого и предыдущего ответа.
Ответ №2:
Я отредактировал свой вопрос. Ошибка, наконец, кажется, исходит из используемой библиотеки (ui kitten).