首页 > 解决方案 > 我如何传递带有状态的函数以响应 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

标签: javascriptreactjsreact-hooks

解决方案


React Context 是一种通过 React 节点树传递数据而无需手动传递 props 的机制。的使用为createContextReact 生态系统中的数据结构创建了一个引用,该引用将给定的数据结构暴露给子节点。

Context.Provider另一方面,为作为 Provider 的子节点的消费组件提供了价值。有一些注意事项需要记住 - 每当您的提供者的值的属性发生变化时,它都会在其所有订阅者中触发重新渲染 - 它是后代。提供者本身不是钩子,因此当使用钩子生成值时,您必须使用设置的新值重新渲染提供者。


您的代码中有几件事需要解决:

  1. useState在一个中使用Context.Provider
  2. 返回useState作为提供者值的结果,并且
  3. 提供给提供者作为值的数据结构

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


推荐阅读