简体   繁体   English

反应上下文中的问题 api

[英]Issue in react context api

Facing issues in react context api, getting undefined while transferring anything using context api.在反应上下文 api 中遇到问题,在使用上下文 api 传输任何内容时变得不确定。 错误 getting this error, getting undefined when sending functions through context 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>
  );
}***

getting undefined in this file while using the function in this file Form.js > and getting error addTransaction is not a function在此文件 Form.js 中使用 function 时在此文件中未定义 > 并收到错误 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; ***

why?为什么?

you are forget to call the context with in From.js .您忘记在From.js中调用上下文。 Because you are created the context hook with same page因为您创建了具有相同页面的上下文挂钩

Better create the context file seperate js file更好地创建上下文文件单独的 js 文件

context.js上下文.js

import React,{createContext}  from 'react';

export const ExpenseTrackerContext = createContext(null);

Contextr.js contextr.js

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

From.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
   ...

Updated - React Doc更新- React 文档

Accepts a context object (the value returned from React.createContext) and returns the current context value for that context.接受上下文 object(从 React.createContext 返回的值)并返回该上下文的当前上下文值。 The current context value is determined by the value prop of the nearest <MyContext.Provider> above the calling component in the tree.当前上下文值由树中调用组件上方最近的 <MyContext.Provider> 的 value prop 确定。

Context passing value only with in tree of children.上下文仅在子树中传递值。 please check Form.js is execute inside the {children} component of context provider.请检查 Form.js 是否在上下文提供程序的 {children} 组件中执行。 if you are using parallel or sibling component its does not work如果您使用的是并行或同级组件,则它不起作用

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

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

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