javascript - 我如何传递带有状态的函数以响应 useContext
问题描述
尝试学习如何使用react hooks。我使用createContext并且想将状态和函数一起传输到其他组件,但我需要有关如何执行此操作的帮助。我也想问这样做是否有意义。
事实上,在我的例子中,我可以通过使用setState来更新状态,但是通过在上下文中定义一个函数,我认为在任何地方使用这个函数更有意义。我错了吗 ?
我的背景是:
export const ExpenseContext = createContext();
export const ExpenseProvider = props => {
const [expense, setExpense] = useState(initialExpenses)
const clearItems = () => {
setExpense([])
}
return ( <
ExpenseContext.Provider value = {
[expense, setExpense],
clearItems
} > {
props.children
} <
/ExpenseContext.Provider>
)
}
我要使用此功能的组件:
const ExpenseList = () => {
const [expense, setExpense] = useContext(ExpenseContext);
const {
clearItem
} = useContext(ExpenseContext);
// const clearItems = () => { normally this works ı know!
// setExpense([])
// }
return ( <
>
<
List > {
expense.map((expense) => {
return <Item key = {
expense.id
}
expense = {
expense
}
/>;
})
} <
/List> <
div className = "text-center" > {
expense.length > 0 && ( <
Button onClick = {
clearItems
}
type = "danger"
shape = "round"
icon = { < DeleteOutlined / >
} >
Clear Expenses <
/Button>
)
} <
/div> < /
>
);
};
在这种情况下,可以直接在组件内使用此功能,而无需尝试转移功能。但我很好奇的是我如何能够传输和接收函数。
注意:当我尝试以这种方式使用它时,我收到此错误:TypeError: Object is not a function
解决方案
React Context 是一种通过 React 节点树传递数据而无需手动传递 props 的机制。的使用为createContext
React 生态系统中的数据结构创建了一个引用,该引用将给定的数据结构暴露给子节点。
Context.Provider
另一方面,为作为 Provider 的子节点的消费组件提供了价值。有一些注意事项需要记住 - 每当您的提供者的值的属性发生变化时,它都会在其所有订阅者中触发重新渲染 - 它是后代。提供者本身不是钩子,因此当使用钩子生成值时,您必须使用设置的新值重新渲染提供者。
您的代码中有几件事需要解决:
useState
在一个中使用Context.Provider
,- 返回
useState
作为提供者值的结果,并且 - 提供给提供者作为值的数据结构
useState
在一个使用Context.Provider
当useState
在一个 react中消费结果时Context
,你必须意识到消费对后代的影响,以及它将产生的影响。React 非常擅长确定要重新渲染的内容和时间,并且它为您提供了控制以进一步限制该行为。useState
但是,它是一个react 功能组件挂钩,每次更新值时都会触发新的渲染。有关于这个的规则,优先级和延迟,但你可以保证重新渲染任何功能组件使用useState
钩子。正是出于这个原因,您希望尽可能将您的提供者/上下文对象视为纯函数。
将结果useState
作为提供者值返回
在您的示例中,您将useState
调用的结果按原样返回给您的上下文提供程序。这给出了一个 React 不能正确订阅和监听变化的对象结构。
提供给提供者作为值的数据结构
在 Provider 中使用状态时,您需要以正确的 JSON 格式返回给提供者,以便它可以订阅值更改,并通知其后代
利用
const providerValue = {
expense,
setExpense,
clearItems
};
<ExpenseContext.Provider value={providerValue}/>
代替:
<ExpenseContext.Provider value = {
[expense, setExpense],
clearItems
} .../>
您提供的上下文提供程序的对象结构无效。请参阅示例代码笔。
在 dev.to上查看这个很棒的useState
例子Context
推荐阅读
- sql-server - 如何从 Visual Studio Mac 连接到 SQL Server?
- python - 在 Python 中清空字典和列表
- javascript - 我从时间选择器中选择的时间未在 TextEditingController 上设置?
- r - 在R中选择列后如何保存列
- r - 将数据框的一列除以另一列的切片
- entity-framework-core - EFCore:迁移和初始数据库创建
- node.js - 中间件是对象而不是函数
- reactjs - 对 https://registry.npmjs.org/expo-template-blank 的请求失败,原因:连接 ETIMEDOUT 104.16.21.35:443
- javascript - 表单构建器中已弃用的 react-native-listview 错误
- javascript - 如何在已创建的编辑器上设置数据?