简体   繁体   English

我如何通过 function 和 state 来反应 useContext

[英]How can ı pass function with state for react useContext

Trying to learn how to use react hooks .尝试学习如何使用react hooks I use createContext and I want to transfer together state and a function to other components, but I need help with how to do this.我使用createContext并且想将 state 和 function 一起转移到其他组件,但我需要有关如何执行此操作的帮助。 I also want to ask if it makes sense to do so.我也想问这样做是否有意义。

In fact, I can update state by using setState in my case, but by defining a function in context, I think it makes more sense to use this function anywhere.事实上,在我的例子中,我可以通过使用setState来更新 state,但是通过在上下文中定义 function,我认为在任何地方使用这个 ZC1C425268E68385D1AB5074C17A94F14 更有意义。 Am I wrong?我错了吗?

my context is:我的背景是:

 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> ) }

The component I want to use this function:我要使用这个 function 的组件:

 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> < / > ); };

in this case, it is possible to use this function directly within the component without trying to transfer the function.在这种情况下,可以直接在组件内使用此 function,而无需尝试传输 function。 But what I'm curious about is how I can manage to transfer and receive functions.但我很好奇的是我如何能够传输和接收函数。

Note: when I try to use it in this way, I get this error: TypeError: Object is not a function注意:当我尝试以这种方式使用它时,出现此错误: TypeError: Object is not a function

The React Context is a mechanism for passing data through a React node tree without having to pass the props manually. React Context 是一种通过 React 节点树传递数据而无需手动传递 props 的机制。 The use of createContext creates a reference for a data structure within React's ecosystem that exposes a given data structure to the children nodes. createContext的使用为 React 生态系统中的数据结构创建了一个引用,该引用将给定的数据结构暴露给子节点。

Context.Provider on the other hand provides a value to consuming components that are children nodes of the Provider.另一方面, Context.Provider为作为 Provider 的子节点的消费组件提供了一个值。 There are a few caveats to remember - whenever the properties of the value your provider is changing, it will trigger a re-render in all of its subscribers - it's descendants.有一些注意事项需要记住 - 每当您的提供者的值的属性发生变化时,它都会在其所有订阅者中触发重新渲染 - 它是后代。 The provider itself is not a hook, therefore when using hooks to generate values, you must re-render the provider with the new values set.提供者本身不是钩子,因此当使用钩子生成值时,您必须使用设置的新值重新渲染提供者。


There are several things in your code that need to be addressed:您的代码中有几件事需要解决:

  1. Using useState in a Context.Provider ,Context.Provider中使用useState
  2. Returning the result of useState as the provider value, anduseState的结果作为提供者值返回,并且
  3. The structure of data provided as the value to provider作为提供者的价值提供的数据结构

Using useState in a Context.ProviderContext.Provider中使用useState

When consuming the result of useState within a react Context , you have to be aware of the implications of consumption in descendants, and the impact that it will have.在 react Context中消费useState的结果时,您必须了解消费在后代中的含义以及它将产生的影响。 React is very good at determining what to re-render and when, and it provides you with control to limit that behavour even more. React 非常擅长确定要重新渲染的内容和时间,并且它为您提供了控制以进一步限制该行为。 useState however, is a react Functional Component Hook that will trigger a new render every time the value is updated.但是, useState是一个反应功能组件挂钩,每次更新值时都会触发新的渲染。 There are rules around this, precedence and delays, but you are guaranteed a re-render of whatever Functional Component consumes the useState hook.对此有一些规则,优先级和延迟,但可以保证重新渲染使用useState挂钩的任何功能组件 It's for this reason you want to treat your providers/context objects as pure functions where possible.正是出于这个原因,您希望尽可能将您的提供者/上下文对象视为纯函数。

Returning the result of useState as the provider value返回useState的结果作为提供者值

Within your example, you return the result of the useState call as-is to your context provider.在您的示例中,您将useState调用的结果按原样返回给您的上下文提供程序。 This gives an object structure that React can't properly subscribe to and listen for changes.这给出了一个 object 结构,React 无法正确订阅和监听更改。

The structure of data provided as the value to provider作为提供者的价值提供的数据结构

When using state with your Provider, you need to return as proper JSON to the provider, so that that it can subscribe to value changes, and notify its descendants将 state 与您的 Provider 一起使用时,您需要将正确的 JSON 返回给 Provider,以便它可以订阅值更改,并通知其后代

Use利用

const providerValue = {
  expense,
  setExpense,
  clearItems
};
<ExpenseContext.Provider value={providerValue}/>

Instead of:代替:

<ExpenseContext.Provider value = {
  [expense, setExpense],
  clearItems
} .../>

The object structure that you're providing the context provider is invalid.您提供的上下文提供程序的 object 结构无效。 See example codepen.请参阅示例代码笔。

Check out this great example on dev.to for useState with Context 在 dev.to 上查看这个很好的例子,了解useState with Context

How I said in the comment you're very close, you pass functions, objects and values the same way我在评论中所说的你非常接近,你以同样的方式传递函数、对象和值

  const [expenses, setExpenses] = useState([]);
  const clearItems = () => {
    setExpenses([]);
  };
  const value = { expenses, setExpenses, clearItems };

Here is a working example这是一个工作示例

https://codesandbox.io/s/silent-worker-yfhbm?file=/src/App.js https://codesandbox.io/s/silent-worker-yfhbm?file=/src/App.js

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM