在反应中映射槽上下文
Map trough context in react
我正在尝试在 React 中映射我的上下文,但它不会呈现任何内容。 (也没有错误消息)。我的应用程序包含上下文提供程序。
My context
import { createContext, useState } from "react";
export const ExpenseContext = createContext();
export const ExpenseProvider = ({ children }) => {
const [expenseType, setExpenseType] = useState();
const [description, setDescription] = useState();
const [value, setValue] = useState();
return (
<ExpenseContext.Provider
value={{
expenseType,
description,
value,
setExpenseType,
setDescription,
setValue,
}}
>
{children}
</ExpenseContext.Provider>
);
};
Where I want to render
import React from "react";
import { useContext } from "react";
import { ExpenseItem } from "./ExpenseItem";
import { ExpenseContext } from "../ExpenseContext";
export const ExpenseList = () => {
const context = useContext(ExpenseContext);
return (
<div>
{Object.keys(context).map((key) => (
<ExpenseItem
expenseType={key.expenseType}
description={key.description}
value={key.value}
></ExpenseItem>
))}
</div>
);
};
My item component
In my item component I'm just rendering {props.description} as a test.
Context data
My context gets data from a form like this:
import React from "react";
import classes from "./Form.module.css";
import { IoIosAddCircleOutline } from "react-icons/io";
import { useContext, useState } from "react";
import { ExpenseContext } from "../ExpenseContext";
export const Form = () => {
const [errorDesc, setErrorDesc] = useState(false);
const [errorSelect, setErrorSelect] = useState(false);
const [errorVal, setErrorVal] = useState(false);
const context = useContext(ExpenseContext);
const onSubmit = (e) => {
e.preventDefault();
if (!context.expenseType) {
setErrorSelect(true);
} else {
setErrorSelect(false);
}
if (!context.description) {
setErrorDesc(true);
} else {
setErrorDesc(false);
}
if (!context.value || isNaN(context.value)) {
setErrorVal(true);
} else {
setErrorVal(false);
}
};
return (
<form className={classes.form} onSubmit={onSubmit}>
<select
className={classes.select}
name="select"
id=""
onChange={(e) => context.setExpenseType(e.target.value)}
>
<option value="" disabled selected>
Expense Type
</option>
<option value="Savings">Savings</option>
<option value="Investments">Investments</option>
<option value="Expenses">Expenses</option>
</select>
<label htmlFor="select">
{errorSelect ? "Please choose an expense type!" : ""}
</label>
<h2 className="">Tracking Expenses</h2>
<hr />
<div className={classes.wrapper}>
<div className={classes.formGroup}>
<input
type="text"
placeholder="Description"
name="description"
className={
errorDesc ? classes.descriptionError : classes.description
}
onChange={(e) => context.setDescription(e.target.value)}
/>
<label htmlFor="description">
{errorDesc ? "Please add a description!" : ""}
</label>
</div>
<div className={classes.formGroup}>
<input
type="text"
placeholder="Amount"
name="value"
className={errorVal ? classes.valueError : classes.value}
onChange={(e) => context.setValue(e.target.value)}
/>
<label htmlFor="value">
{errorVal ? "Please add a valid value!" : ""}
</label>
</div>
<div className={classes.formGroup}>
<input type="submit" className={classes.submit} />
</div>
</div>
</form>
);
};
当您在 Object.keys(context)
上映射时,您实际映射的是 ["expenseType","description","value","setExpenseType","setDescription","setValue"]
,因为这些是您的上下文提供的对象的键
因为它们是字符串,所以 key.expenseType
和 key.description
是未定义的。
根据我的阅读,我很确定你正在尝试做其他事情,你可能希望你的上下文提供一个你映射的对象数组,比如
import { createContext, useState } from "react";
export const ExpenseContext = createContext();
export const ExpenseProvider = ({ children }) => {
const [expenses, setExpenses] = useState([]);
return (
<ExpenseContext.Provider
value={{
expenses, setExpenses
}}
>
{children}
</ExpenseContext.Provider>
);
};
expenses
的成员是具有 expenseType
、description
和 value
属性的对象,我说得对吗?
我正在尝试在 React 中映射我的上下文,但它不会呈现任何内容。 (也没有错误消息)。我的应用程序包含上下文提供程序。
My context
import { createContext, useState } from "react";
export const ExpenseContext = createContext();
export const ExpenseProvider = ({ children }) => {
const [expenseType, setExpenseType] = useState();
const [description, setDescription] = useState();
const [value, setValue] = useState();
return (
<ExpenseContext.Provider
value={{
expenseType,
description,
value,
setExpenseType,
setDescription,
setValue,
}}
>
{children}
</ExpenseContext.Provider>
);
};
Where I want to render
import React from "react";
import { useContext } from "react";
import { ExpenseItem } from "./ExpenseItem";
import { ExpenseContext } from "../ExpenseContext";
export const ExpenseList = () => {
const context = useContext(ExpenseContext);
return (
<div>
{Object.keys(context).map((key) => (
<ExpenseItem
expenseType={key.expenseType}
description={key.description}
value={key.value}
></ExpenseItem>
))}
</div>
);
};
My item component In my item component I'm just rendering {props.description} as a test. Context data My context gets data from a form like this:
import React from "react";
import classes from "./Form.module.css";
import { IoIosAddCircleOutline } from "react-icons/io";
import { useContext, useState } from "react";
import { ExpenseContext } from "../ExpenseContext";
export const Form = () => {
const [errorDesc, setErrorDesc] = useState(false);
const [errorSelect, setErrorSelect] = useState(false);
const [errorVal, setErrorVal] = useState(false);
const context = useContext(ExpenseContext);
const onSubmit = (e) => {
e.preventDefault();
if (!context.expenseType) {
setErrorSelect(true);
} else {
setErrorSelect(false);
}
if (!context.description) {
setErrorDesc(true);
} else {
setErrorDesc(false);
}
if (!context.value || isNaN(context.value)) {
setErrorVal(true);
} else {
setErrorVal(false);
}
};
return (
<form className={classes.form} onSubmit={onSubmit}>
<select
className={classes.select}
name="select"
id=""
onChange={(e) => context.setExpenseType(e.target.value)}
>
<option value="" disabled selected>
Expense Type
</option>
<option value="Savings">Savings</option>
<option value="Investments">Investments</option>
<option value="Expenses">Expenses</option>
</select>
<label htmlFor="select">
{errorSelect ? "Please choose an expense type!" : ""}
</label>
<h2 className="">Tracking Expenses</h2>
<hr />
<div className={classes.wrapper}>
<div className={classes.formGroup}>
<input
type="text"
placeholder="Description"
name="description"
className={
errorDesc ? classes.descriptionError : classes.description
}
onChange={(e) => context.setDescription(e.target.value)}
/>
<label htmlFor="description">
{errorDesc ? "Please add a description!" : ""}
</label>
</div>
<div className={classes.formGroup}>
<input
type="text"
placeholder="Amount"
name="value"
className={errorVal ? classes.valueError : classes.value}
onChange={(e) => context.setValue(e.target.value)}
/>
<label htmlFor="value">
{errorVal ? "Please add a valid value!" : ""}
</label>
</div>
<div className={classes.formGroup}>
<input type="submit" className={classes.submit} />
</div>
</div>
</form>
);
};
当您在 Object.keys(context)
上映射时,您实际映射的是 ["expenseType","description","value","setExpenseType","setDescription","setValue"]
,因为这些是您的上下文提供的对象的键
因为它们是字符串,所以 key.expenseType
和 key.description
是未定义的。
根据我的阅读,我很确定你正在尝试做其他事情,你可能希望你的上下文提供一个你映射的对象数组,比如
import { createContext, useState } from "react";
export const ExpenseContext = createContext();
export const ExpenseProvider = ({ children }) => {
const [expenses, setExpenses] = useState([]);
return (
<ExpenseContext.Provider
value={{
expenses, setExpenses
}}
>
{children}
</ExpenseContext.Provider>
);
};
expenses
的成员是具有 expenseType
、description
和 value
属性的对象,我说得对吗?