在 ReactJS 上下文中使用对象 - 对象中的方法导致 属性 'myMethod' 在类型 'unknown' 上不存在
Using object in ReactJS Context - method in object causes Property 'myMethod' does not exist on type 'unknown'
我第一次尝试使用上下文,我有一个创建上下文的 Reactjs 库,然后在主应用程序中更新上下文并作为 app.js 中的上下文提供程序传递。
我的图书馆里有以下这些:
import * as React from "react";
export const MyContext = React.createContext(null);
export const MyContextProvider = MyContext.Provider;
export const MyContextConsumer = MyContext.Consumer;
export class MyClass
{
constructor()
{
....
}
...
myMethod(param1, param2 = null)
{
...
}
然后在我的主项目里面app.tsx我有以下内容:
const my_class = new MyClass();
my_class.initialise("param1", "param2", "param3");
<MyContextProvider value={my_class}>
<ErrorBoundary>
<BrowserRouter>
<Routes>
<Route index element={<Home />} />
<Route path='/blog' element={<BlogHome />} />
<Route path='/blog/:slug' element={<BlogPost />} />
<Route path='*' element={<NotFound />} />
</Routes>
</BrowserRouter>
</ErrorBoundary>
</MyContextProvider>
然后在我的子组件中,在这种情况下 NotFound
组件,然后我执行以下操作:
const my_class = useContext(MyContext);
console.log("My class context", my_class);
my_class.myMethod(err, "Low");
编译失败,因为方法 myMethod
抛出错误 Property 'myMethod' does not exist on type 'unknown'
当我删除对 myMethod
的调用并只打印 my_class
时,该对象具有传递给构造函数的所有内容,我可以看到其中的方法,尽管它在 [[Prototype ]] 对象,但不确定这是否符合预期,或者我是否应该以某种方式引用它来访问方法调用。
很难说没有 mcve,但我猜你没有正确使用 MyContext
。也就是说,通常情况下,上下文将是一个具有属性和方法的对象:
value: {
firstName: "Bob", // value from state
lastName: "Smith", // value from state
changeFirstName: () => {}, // some sort of state updater
changeLastName: () => {}, // some sort of state updater
otherCallback: () => {}, // some sort of callback that affects the UI
...etc
}
以上内容遵循更标准的方法,因为值来自状态(来自共享状态对象或分离的 useState
值)和一些包含状态的方法 setters 来更新这些值因此。由于您使用的是 useContext
挂钩,因此函数式编程 (FP) 方法会更有意义;但是,您似乎正在尝试将 OOP(普通 class)与 FP 混合使用。除非绝对需要使用 class,否则我建议使用上面的平面对象方法。
就是说,这是在上下文中使用普通 class 的方法...
工作演示:
理想情况下,您需要使用创建上下文的 class 字段初始化上下文:
import { createContext, useContext } from "react";
import User, { IUser } from "./User";
const user = new User("Bob", "Smith");
export const UserContext = createContext<IUser>(user);
export const useUserContext = () => useContext(UserContext);
然后,导入 UserContext
上下文和 useUserContext
挂钩,并在您的应用程序的顶层使用它们:
import { UserContext, useUserContext } from "./UserContext";
const App = (): ReactElement => (
<UserContext.Provider value={useUserContext()}>
{...}
</UserContext.Provider>
);
export default App;
在子组件中,您可以导入 useUserContext
挂钩并相应地使用其 return 值的 fields/properties:
import { useUserContext } from "./UserContext";
import { ReactElement } from "react";
const Main = (): ReactElement => {
const user = useUserContext();
return (
<main className="main">
<h1>User Context</h1>
<h2 className="user">
<strong>First Name:</strong> {user.firstName}
</h2>
<h2 className="user">
<strong>Last Name:</strong> {user.lastName}
</h2>
<h2 className="user">
<strong>Combined Name:</strong> {user.combinedName()}
</h2>
</main>
);
};
export default Main;
但是这种方法有问题!
您要 运行 解决的问题是,如果您计划 manipulating/updating class 中的字段... React 不会 处理可变字段的变化。因此,如果您更改 class 字段,该更改 不会 重新呈现应用程序(如上面的演示所示)。
相反,您需要利用 state(来自 React Component
class 或钩子)和某种 操纵状态 的回调(调用 this.setState({...})
的回调或调用 useState
状态 setter 的回调)。因此,在上下文中使用普通的 class 确实没有多大意义,因为它只能是静态的 stored/utilized.
这是一个如何在上下文中使用状态的示例:
我认为这个问题是由我的主项目中的打字稿问题引起的。
我有 const my_class = useContext(MyContext)
的地方我必须设置 my_class 的类型 const my_class : MyContext = useContext(MyContext)
解决了问题
我第一次尝试使用上下文,我有一个创建上下文的 Reactjs 库,然后在主应用程序中更新上下文并作为 app.js 中的上下文提供程序传递。
我的图书馆里有以下这些:
import * as React from "react";
export const MyContext = React.createContext(null);
export const MyContextProvider = MyContext.Provider;
export const MyContextConsumer = MyContext.Consumer;
export class MyClass
{
constructor()
{
....
}
...
myMethod(param1, param2 = null)
{
...
}
然后在我的主项目里面app.tsx我有以下内容:
const my_class = new MyClass();
my_class.initialise("param1", "param2", "param3");
<MyContextProvider value={my_class}>
<ErrorBoundary>
<BrowserRouter>
<Routes>
<Route index element={<Home />} />
<Route path='/blog' element={<BlogHome />} />
<Route path='/blog/:slug' element={<BlogPost />} />
<Route path='*' element={<NotFound />} />
</Routes>
</BrowserRouter>
</ErrorBoundary>
</MyContextProvider>
然后在我的子组件中,在这种情况下 NotFound
组件,然后我执行以下操作:
const my_class = useContext(MyContext);
console.log("My class context", my_class);
my_class.myMethod(err, "Low");
编译失败,因为方法 myMethod
抛出错误 Property 'myMethod' does not exist on type 'unknown'
当我删除对 myMethod
的调用并只打印 my_class
时,该对象具有传递给构造函数的所有内容,我可以看到其中的方法,尽管它在 [[Prototype ]] 对象,但不确定这是否符合预期,或者我是否应该以某种方式引用它来访问方法调用。
很难说没有 mcve,但我猜你没有正确使用 MyContext
。也就是说,通常情况下,上下文将是一个具有属性和方法的对象:
value: {
firstName: "Bob", // value from state
lastName: "Smith", // value from state
changeFirstName: () => {}, // some sort of state updater
changeLastName: () => {}, // some sort of state updater
otherCallback: () => {}, // some sort of callback that affects the UI
...etc
}
以上内容遵循更标准的方法,因为值来自状态(来自共享状态对象或分离的 useState
值)和一些包含状态的方法 setters 来更新这些值因此。由于您使用的是 useContext
挂钩,因此函数式编程 (FP) 方法会更有意义;但是,您似乎正在尝试将 OOP(普通 class)与 FP 混合使用。除非绝对需要使用 class,否则我建议使用上面的平面对象方法。
就是说,这是在上下文中使用普通 class 的方法...
工作演示:
理想情况下,您需要使用创建上下文的 class 字段初始化上下文:
import { createContext, useContext } from "react";
import User, { IUser } from "./User";
const user = new User("Bob", "Smith");
export const UserContext = createContext<IUser>(user);
export const useUserContext = () => useContext(UserContext);
然后,导入 UserContext
上下文和 useUserContext
挂钩,并在您的应用程序的顶层使用它们:
import { UserContext, useUserContext } from "./UserContext";
const App = (): ReactElement => (
<UserContext.Provider value={useUserContext()}>
{...}
</UserContext.Provider>
);
export default App;
在子组件中,您可以导入 useUserContext
挂钩并相应地使用其 return 值的 fields/properties:
import { useUserContext } from "./UserContext";
import { ReactElement } from "react";
const Main = (): ReactElement => {
const user = useUserContext();
return (
<main className="main">
<h1>User Context</h1>
<h2 className="user">
<strong>First Name:</strong> {user.firstName}
</h2>
<h2 className="user">
<strong>Last Name:</strong> {user.lastName}
</h2>
<h2 className="user">
<strong>Combined Name:</strong> {user.combinedName()}
</h2>
</main>
);
};
export default Main;
但是这种方法有问题!
您要 运行 解决的问题是,如果您计划 manipulating/updating class 中的字段... React 不会 处理可变字段的变化。因此,如果您更改 class 字段,该更改 不会 重新呈现应用程序(如上面的演示所示)。
相反,您需要利用 state(来自 React Component
class 或钩子)和某种 操纵状态 的回调(调用 this.setState({...})
的回调或调用 useState
状态 setter 的回调)。因此,在上下文中使用普通的 class 确实没有多大意义,因为它只能是静态的 stored/utilized.
这是一个如何在上下文中使用状态的示例:
我认为这个问题是由我的主项目中的打字稿问题引起的。
我有 const my_class = useContext(MyContext)
的地方我必须设置 my_class 的类型 const my_class : MyContext = useContext(MyContext)
解决了问题