#reactjs #typescript #react-native #use-context
#reactjs #typescript #react-native #использование-context
Вопрос:
У меня возникает проблема, когда я пытаюсь использовать функции из контекста внутри дочернего компонента в приложении React native для Android.
Ниже приведен мой код для контекста и компонента формы, в котором я его использую (сокращено для краткости).
Объект «isFormOpen» может быть прочитан без проблем изнутри любых дочерних элементов, которые завернуты в провайдере, но когда я пытаюсь вызвать функцию «toggleForm» из того же дочернего компонента, он ничего не делает, ошибок консоли тоже нет.
У меня есть другой контекст, который идентичен по структуре и синтаксису, за исключением имен переменных и функций и т.д., и это работает отлично, поэтому я немного смущен тем, почему это не работает. Я удалил другой контекст, думая, что может быть какой-то конфликт, но не решил его.
AccountContext.tsx
import React, { FC, createContext, useContext, useState } from 'react';
interface AccountContextType {
isFormOpen: boolean,
toggleForm: (toggle: boolean) => void
};
export const AccountContext = createContext<AccountContextType>({
isFormOpen: false,
toggleForm: () => null
});
export const AccountContextProvider: FC = props => {
const [formOpen, setFormOpen] = useState<boolean>(false);
const toggleForm = (toggle: boolean) => {
setFormOpen(toggle);
}
const value: AccountContextType = {
isFormOpen: formOpen,
toggleForm
}
return (
<AccountContext.Provider value={value}>
{props.children}
</AccountContext.Provider>
)
}
export const useAccountContext = () => useContext(AccountContext);
TrackUploadForm.js
import React from 'react';
import { SafeAreaView } from 'react-native';
import { Button } from 'react-native-paper';
import { useAccountContext } from '../contexts/AccountContext';
import { AccountContextProvider } from '../contexts/AccountContext';
const TrackUploadForm = () => {
const accountContext = useAccountContext();
return (
<AccountContextProvider>
<SafeAreaView>
<Button onPress={() => accountContext.toggleForm(false)} mode='outlined'>Cancel</Button>
</SafeAreaView>
</AccountContextProvider>
)
};
export default TrackUploadForm;
Ответ №1:
useAccountContext
вызывается вне поставщика
export default function App() {
return (
<AccountContextProvider>
<Content />
</AccountContextProvider>
);
}
const Content = () => {
const accountContext = useAccountContext();
return (
<div className="App">
<h1>{accountContext.isFormOpen ? "true" : "false"}</h1>
<Button onPress={() => accountContext.toggleForm(false)} mode='outlined'>Cancel</Button>
</div>
);
};
accountContext.toggleForm(false)
<— всегда false, измените его наaccountContext.toggleForm(!accountContext.isFormOpen)
Вместе мы имеем https://codesandbox.io/s/cranky-panini-yo129
Комментарии:
1. Ого, это сработало. Причина, по которой я не думал, что это произойдет, заключается в том, что я переместил оболочку вверх по дереву, но не так далеко, как обертывание всего приложения. У меня сложилось впечатление, что вы можете обернуть любой компонент, который вы хотите, и все его дочерние элементы могут использовать контекст, и смысл этого в том, чтобы разрешить только определенным компонентам использовать контекст. Спасибо.