1

I am trying to render a component if (age<18) in the next block of code

 var split_dob = dateOfBirth.split("-");
    var month = split_dob[1];
var day = split_dob[2];
var year = split_dob[0];
var dob_asdate = new Date(year, month, day);
var today = new Date();
var mili_dif = Math.abs(today.getTime() - dob_asdate.getTime());
var age = (mili_dif / (1000 * 3600 * 24 * 365.25));
console.log(age);
if(age<18){setEligible(true)}

here's useState hook:

const [uneligible,setEligible] = React.useState(
    false  // default value
    )

and here's how I am trying to render it:

<div>{uneligible&& <Alert variant="filled" severity="error">
  This is an error alert — check it out!
</Alert>}</div>

in the actual project there's no errors, just the component not rendering and I made minimised version of the code here but it still has problem in rendering: https://codesandbox.io/s/thirsty-sara-jiomm?file=/src/App.js

3 Answers 3

1

You don't actually need state here. Just use const uneligible = age<18 and get rid of the useState code, and it will work okay. If you put uneligible in the state you create a render loop, as setting it triggers a re-render, which sets the state again and triggers another re-render, etc.

const ProfilePage = (props) => {
  var dateOfBirth = "2007-01-01";
  var split_dob = dateOfBirth.split("-");
  var month = split_dob[1];
  var day = split_dob[2];
  var year = split_dob[0];
  var dob_asdate = new Date(year, month, day);
  var today = new Date();
  var mili_dif = Math.abs(today.getTime() - dob_asdate.getTime());
  var age = mili_dif / (1000 * 3600 * 24 * 365.25);
  console.log(age);
  const uneligible = age < 18;

  return (
    <div>
      {uneligible && (
        <Alert variant="filled" severity="error">
          This is an error alert — check it out!
        </Alert>
      )}
    </div>
  );
};

Sandbox example

Sign up to request clarification or add additional context in comments.

Comments

0

Get the dateOfBirth, and set uneligible as a standard const (useMemo for slight optimization if needed). This will prevent the loop in which render sets the state, and setting the state causes a re-render, which sets the state...

const { useMemo } = React;

const ProfilePage = ({ dateOfBirth }) => {
  const uneligible = useMemo(() => {
    const mili_dif = Math.abs(Date.now() - Date.parse(dateOfBirth));
    const age = mili_dif / (1000 * 3600 * 24 * 365.25);

    return age < 18;
  }, [dateOfBirth]);

  return (
    <div>
      {uneligible && (
        <div variant="filled" severity="error">
          This is an error alert — check it out!
        </div>
      )}
    </div>
  );
};

ReactDOM.render(
  <ProfilePage dateOfBirth="2007-01-01" />, 
  root
);
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>

<div id="root"></div>

Comments

0

The function re-renders again and again because you set the state immediately. Solution:

import React from "react";

import Alert from "@material-ui/lab/Alert";

const ProfilePage = (props) => {
  
  const isEligible = () => {
    var dateOfBirth = "2007-01-01";
    var split_dob = dateOfBirth.split("-");
    var month = split_dob[1];
    var day = split_dob[2];
    var year = split_dob[0];
    var dob_asdate = new Date(year, month, day);
    var today = new Date();
    var mili_dif = Math.abs(today.getTime() - dob_asdate.getTime());
    var age = mili_dif / (1000 * 3600 * 24 * 365.25);
    console.log(age);
    return age < 18;
  }


  return (
    <div>
      {isEligible() && (
        <Alert variant="filled" severity="error">
          This is an error alert — check it out!
        </Alert>
      )}
    </div>
  );
};

export default ProfilePage;


Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.