Q:

tag:ReactJS Context.Provider value is not updated

i'am trying to useContext() but the Provider doesnt pass the value, even if I use a fake value like:
<TestContext.Provider value="2000">
and keep the default value where the Context is initialised:
export const TestContext = createContext(5000);
so there is the code:
PARENT COMPONENT
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;

CHILD COMPONENT
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;

By advance thanks for your help

A:

The Provider from docs:
https://reactjs.org/docs/context.html#contextprovider

Accepts a value prop to be passed to consuming components that are descendants of this Provider

Your Provider is at top of User component, which means that all components inside the provider gets the context value. Your Recipes component is not part of that tree but the App component itself.
You might need to add the Provider to the top of 'App' or re-structure your components accordingly.
for eg., this will solve your case as Recipes is part of the hierarchy.
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>
  );
}

