标签:ReactJS上下文.提供程序值未更新



我正在尝试使用Context((,但提供者没有传递值,即使我使用了像这样的假值

<TestContext.Provider value="2000">

并保持上下文初始化时的默认值:

export const TestContext = createContext(5000);

所以有一个代码:

父组件

import React, { useState, useEffect, createContext } from "react";
import Axios from "axios";
import { makeStyles } from "@material-ui/core/styles";
import Button from "@material-ui/core/Button";
import Card from "@material-ui/core/Card";
import CardActions from "@material-ui/core/CardActions";
import CardContent from "@material-ui/core/CardContent";
import Container from "@material-ui/core/Container";
import Divider from "@material-ui/core/Divider";
import Grid from "@material-ui/core/Grid";
import ListItemText from "@material-ui/core/ListItemText";
import Paper from "@material-ui/core/Paper";
import Typography from "@material-ui/core/Typography";
// import style
const useStyles = makeStyles({
root: {
minWidth: 275,
},
title: {
fontSize: 14,
},
pos: {
marginBottom: 12,
},
});

export const TestContext = createContext(5000);
function User() {
const classes = useStyles();
/* get all users */
const [allUsers, setAllUsers] = useState([{}]);
const getAllUsers = () => {
const url = `http://localhost:5000/api/users`;
Axios.get(url)
.then((response) => response.data)
.then((data) => setAllUsers(data));
};
useEffect(() => {
return getAllUsers();
}, []);
/* get one user */
const [user, setUser] = useState([{}]);
const getOneUser = (userId) => {
const url = `http://localhost:5000/api/users/${userId}`;
Axios.get(url)
.then((response) => response.data)
.then((data) => setUser(data));
};
useEffect(() => {
getOneUser();
}, [allUsers]);
/* init energy */
const [energyConsuption, setEnergyConsuption] = useState({});
const calcDailyEnergyConsumption = () => {
// for a male
const basalMetabolicRate =
1.083 *
Math.pow(weight, 0.48) *
Math.pow(height, 0.5) *
Math.pow(age, -0.13) *
191;
const dailyEnergyConsumption = basalMetabolicRate * activity;
return setEnergyConsuption({
mb_rate: basalMetabolicRate.toFixed(2),
daily_energy: dailyEnergyConsumption.toFixed(2),
});
};
useEffect(() => {
calcDailyEnergyConsumption();
}, [user]);
/* init Proteins, Lipids, Glucids state */
const [PLG, setPLG] = useState({});
/* init info needed by user */
const weight = user.weight;
const height = user.height;
const age = user.age;
const activity = 1.4;
/* calculate proteins / lipids / glucids ratio */
const calcLipGlucProt = () => {
// DEC means Daily Energy Consuption
let DEC = energyConsuption.daily_energy;
const proteins = user.weight * 1.8;
DEC = DEC - proteins * 4;
const lipids = user.weight * 1;
DEC = DEC - lipids * 9;
const glucids = DEC / 4;
return setPLG({
proteins: proteins.toFixed(2),
lipids: lipids.toFixed(2),
glucids: glucids.toFixed(2),
});
};
useEffect(() => {
calcLipGlucProt();
}, [energyConsuption]);
return (
<Container>
<h1>{energyConsuption.daily_energy}</h1>
<TestContext.Provider value="2000">
<Grid container spacing={1}>
{allUsers.map((userDetail) => (
<Grid item xs={2}>
<Paper>
<Button
onClick={() => getOneUser(userDetail.id)}
>
{userDetail.id} {userDetail.firstname}
</Button>
</Paper>
</Grid>
))}
</Grid>
<Card className={classes.root}>
<CardContent>
<Typography
variant="h5"
component="h2"
gutterBottom
>{`Bonjour ${user.firstname} ${user.lastname}`}</Typography>
<Divider />
<Typography
className={classes.pos}
color="textSecondary"
>
age : {user.age} ans
</Typography>
<Typography
className={classes.pos}
color="textSecondary"
>
taille : {user.height} m
</Typography>
<Typography
className={classes.pos}
color="textSecondary"
>
poid : {user.weight} kg
</Typography>
<Typography
className={classes.pos}
color="textSecondary"
>
activité : {user.id_activity} (sédentaire)
</Typography>
<Typography
className={classes.pos}
color="textSecondary"
>
objectif : {user.id_goal}(perdre du poid)
</Typography>
<Divider />
<Typography display="block" paragraph gutterBottom>
Votre <u>métabolisme basal</u> est de
<strong>
{" "}
{energyConsuption.mb_rate} calories
</strong>{" "}
et votre <u>dépense énergétique journalière</u> est
de
<strong>
{energyConsuption.daily_energy} calories
</strong>
</Typography>
<Typography display="block">
Vous devez consommer idéalement
<ListItemText href="#simple-list">
- {PLG.proteins} grammes de protéines
</ListItemText>
<ListItemText href="#simple-list">
- {PLG.lipids} grammes de lipides
</ListItemText>
<ListItemText href="#simple-list">
- {PLG.glucids} grammes de glucides
</ListItemText>
</Typography>
<Divider />
<Typography
variant="caption"
display="block"
gutterBottom
>
Ces informations ne remplace en aucun cas l'avis
médical d'un expert.
</Typography>
</CardContent>
<CardActions>
<Button size="small">Mettre à jour mes infos</Button>
</CardActions>
</Card>
</TestContext.Provider>
</Container>
);
}
export default User;

儿童组件

import React, { useState, useEffect, useContext } from "react";
import { TestContext } from "../Users/Users";
import Axios from "axios";
import Container from "@material-ui/core/Container";
import Grid from "@material-ui/core/Grid";
import Typography from "@material-ui/core/Typography";
import Card from "@material-ui/core/Card";
import CardActions from "@material-ui/core/CardActions";
import CardContent from "@material-ui/core/CardContent";
import Button from "@material-ui/core/Button";
import TextField from "@material-ui/core/TextField";
import Paper from "@material-ui/core/Paper";
function Recipes() {
const value = useContext(TestContext);
// console.log("Context", TestContext);
const [allFoods, setAllFoods] = useState([{}]);
const [food, setFood] = useState([{}]);
const [foodQuantity, setFoodQuantity] = useState(0);
const getAllFoods = () => {
const url = "http://localhost:5000/api/foods";
Axios.get(url)
.then((response) => response.data)
.then((data) => setAllFoods(data));
};
useEffect(() => {
return getAllFoods();
}, []);
const getOneFood = (foodId) => {
const url = `http://localhost:5000/api/foods/${foodId}`;
Axios.get(url)
.then((response) => response.data)
.then((data) => setFood(data));
};
useEffect(() => {
getOneFood();
}, [allFoods]);
const getFoodName = allFoods.map((foodDetail) => (
<Button onClick={() => getOneFood(foodDetail.id)}>
<Paper>{foodDetail.name}</Paper>
</Button>
));
const calcFoodQuantity = () => {
const total = 100 * (calories / food.calories);
setFoodQuantity(total.toFixed(2));
};
return (
<Container>
<Card>
<Grid container spacing={1}>
{getFoodName}
</Grid>
<Typography variant="h2" gutterBottom>
Calculer une recette pour {value} calories
</Typography>
<CardContent>
<Typography>{food.name}</Typography>
<Typography>{food.calories} cals</Typography>
</CardContent>
<CardActions>
<Button
size="small"
color="secondary"
onClick={() => calcFoodQuantity()}
>
Calculer
</Button>
<Typography>
il vous faut {foodQuantity} grammes de {food.name} pour
atteindre votre dépense énergétique journalière
</Typography>
</CardActions>
</Card>
</Container>
);
}
export default Recipes;

提前感谢您的帮助

文档中的Provider:https://reactjs.org/docs/context.html#contextprovider

接受要传递给作为此提供程序的后代的消耗组件的值道具

您的提供程序位于User组件的顶部,这意味着提供程序内的所有组件都将获得上下文值。您的Recipes组件不是该树的一部分,而是App组件本身。

您可能需要将提供商添加到"应用程序"的顶部,或者相应地重新构建组件。

例如,这将解决您的问题,因为Recipes是层次结构的一部分。

function App() {
return (
<Container>
<TestContext.Provider value="TEST"> // My wealth for my family under me
<Users /> //Users and all child components get them
<Menu /> // Me too. my family tree gets context
<Switch>
<Route exact path="/" />
<Route path="/aliments" component={Foods} /> // Me too. my family gets context
<Route path="/recettes" component={Recipes} /> // Me too. my family gets context
<Route path="/repas" component={Meals} /> // Me too. my family gets context
<Route path="/planning" component={Planning} /> // Me too. my family  gets too
</Switch>
</TestContext.Provider>
</Container>
);
}

相关内容

  • 没有找到相关文章

最新更新