【问题标题】:Issue in react context api反应上下文 api 中的问题
【发布时间】:2021-01-29 05:37:22
【问题描述】:

在反应上下文 api 中面临问题,在使用上下文 api 传输任何内容时变得未定义。 收到此错误,通过上下文 api 发送函数时未定义。

*** Context.js

import React, { useReducer, createContext } from "react";
import contextReducer from "./contextReducer";

const initialState = [];

export const ExpenseTrackerContext = createContext(initialState);

export function Provider({ children }) {
  const [transactions, dispatch] = useReducer(contextReducer, initialState);`enter code here`

  const deleteTransaction = (id) =>
    dispatch({ type: "DELETE_TRANSACTION", payload: id });
  const addTransaction = (transaction) =>
    dispatch({ type: "ADD_TRANSACTION", payload: transaction });
 

  return (
    <ExpenseTrackerContext.Provider
      value={{
        deleteTransaction,
        addTransaction,
        transactions,
      }}
    >
      {children}
    </ExpenseTrackerContext.Provider>
  );
}***

使用此文件 Form.js 中的函数时在此文件中未定义 > 并收到错误 addTransaction is not a function

 *** Form.js 
 import React, { useState, useContext } from "react";
    import {
      TextField,
      Typography,
      Grid,
      FormControl,
      InputLabel,
      Select,
      MenuItem,
      Button,
    } from "@material-ui/core";
    
  
    import { ExpenseTrackerContext } from "../../context/context";
    
    import { v4 as uuidv4 } from "uuid";
    import useStyles from "./styles";
    
    const initialState = {
      amount: "",
      category: "",
      type: "Income",
      date: new Date(),
    };
    
    const Form = (props) => {
      const classes = useStyles();
      const [formData, setFormData] = useState(initialState);
    
      // console.log(useContext(ExpenseTrackerContext));
    
      const { addTransaction } = useContext(ExpenseTrackerContext);
    
      console.log("context: " + ExpenseTrackerContext.displayName);
      console.log("add: " + typeof addTransaction);
    
      const createTransaction = () => {
        const transaction = {
          ...formData,
          amount: Number(formData.amount),
          id: uuidv4(),
        };
        addTransaction(transaction);
        setFormData(initialState);
      };
      return (
        <Grid container spacing={2}>
          <Grid item xs={12}>
            <Typography align="center" variant="subtitle2" gutterBottom>
              ...
            </Typography>
          </Grid>
          <Grid item xs={6}>
            <FormControl fullWidth>
              <InputLabel>Type</InputLabel>
              <Select
                value={formData.type}
                onChange={(e) => setFormData({ ...formData, type: e.target.value })}
              >
                <MenuItem value="Income">Income</MenuItem>
                <MenuItem value="Expense">Expense</MenuItem>
              </Select>
            </FormControl>
          </Grid>
          <Grid item xs={6}>
            <FormControl fullWidth>
              <InputLabel>Category</InputLabel>
              <Select
                value={formData.category}
                onChange={(e) =>
                  setFormData({ ...formData, category: e.target.value })
                }
              >
                <MenuItem value="business">Business</MenuItem>
                <MenuItem value="Salary">Salary</MenuItem>
              </Select>
            </FormControl>
          </Grid>
    
          <Grid item xs={6}>
            <TextField
              type="number"
              label="Amount"
              fullWidth
              value={formData.amount}
              onChange={(e) => setFormData({ ...formData, amount: e.target.value })}
            />
          </Grid>
    
          <Grid item xs={6}>
            <TextField
              type="date"
              label=" "
              fullWidth
              value={formData.date}
              onChange={(e) => setFormData({ ...formData, date: e.target.value })}
            />
          </Grid>
          <Button
            className={classes.button}
            variant="outlined"
            color="primary"
            fullWidth
            onClick={createTransaction}
          >
            Create
          </Button>
        </Grid>
      );
    };
    
    export default Form; ***

【问题讨论】:

  • 请张贴你addTransaction功能使用页面。 Form.js。我认为您忘记在From.js 中启动上下文。因为您创建了具有相同页面的上下文挂钩
  • 您还没有添加相关代码,实际发生此错误的位置(Form.js

标签: javascript reactjs dom undefined react-context


【解决方案1】:

为什么?

您忘记在From.js 中调用上下文。因为您创建了具有相同页面的上下文挂钩

最好创建上下文文件单独的js文件

context.js

import React,{createContext}  from 'react';

export const ExpenseTrackerContext = createContext(null);

Contextr.js

   import {ExpenseTrackerContext} from './context.js' // path of context.js

来自.js

import React,{useContext}  from 'react';
import {ExpenseTrackerContext} from './context.js' // path of context.js

   export default function From(props){
   const expContext = useContext(ExpenseTrackerContext);
   
   expContext.addTransaction()// you could call like this
   ...

更新 - React Doc

接受一个上下文对象(从 React.createContext 返回的值) 并返回该上下文的当前上下文值。目前的 上下文值由最近的 value 属性决定 在树中调用组件上方。

上下文仅在子树中传递值。请检查 Form.js 是否在上下文提供程序的 {children} 组件内执行。如果您使用并行或同级组件,则它不起作用

<ExpenseTrackerContext.Provider
      value={{
        deleteTransaction,
        addTransaction,
        transactions,
      }}
    >
      {children} // From.js present in this children in any one of the tree otherwise undefined (value only passed inside the provider component tree)
    </ExpenseTrackerContext.Provider>

【讨论】:

  • 我已经尝试过了,但得到了同样的错误。
  • 上下文仅在子树中传递值。请检查Form.js 是否在上下文提供程序的{children} 组件内执行。如果您使用并行或同级组件,则它不起作用。检查我的更新答案
  • 谢谢,帮了大忙。
猜你喜欢
  • 2016-07-25
  • 1970-01-01
  • 1970-01-01
  • 2021-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-11
相关资源
最近更新 更多