3

I'm trying to create a table which changes dynamically. The number of its columns changes according to the number of days of the month (28, 29, 30, or 31).

I created the table manually (but the number of columns is fixed to 31):

https://i.sstatic.net/pAvPu.png

Here is the component in which I tried to select the number of columns manually according to the number of days of the current month (28,29,30,31), it shows nothing in the browser:

const Test = () => {
    // Number of days in the current month
    function daysInCurrentMonth() {
        var now = new Date();
        return new Date(now.getFullYear(), now.getMonth()+1, 0).getDate();
    }

    let a = daysInCurrentMonth();
    return (
        <div>
            <table>
                <tbody>
                    <tr>
                        {() => {
                            for(let i=1;i<=a;i++){
                                 <td>{i}</td>
                            }
                        }}
                    </tr>
                </tbody>
            </table>
        </div>
    );
}

export default Test;

How can I use a for loop inside this code?

3 Answers 3

14

You need to return the td's from the function you're writing in JSX and call the function as well like this:

return (
  <div>
    <table>
      <tbody>
        <tr>
          {(() => {
            let td = [];
            for (let i = 1; i <= a; i++) {
              td.push(<td key={i}>{i}</td>);
            }
            return td;
          })()}
        </tr>
      </tbody>
    </table>
  </div>
);

A more efficient way to render it is to extract the function outside the JSX:

function daysInCurrentMonth() {
   var now = new Date();
   return new Date(now.getFullYear(), now.getMonth() + 1, 0).getDate();
}

let a = daysInCurrentMonth();

const renderTD = () => {
  let td = [];
  for (let i = 1; i <= a; i++) {
    td.push(<td key={i}>{i}</td>);
  }
  return td;
};

return (
  <div>
    <table>
      <tbody>
        <tr>{renderTD()}</tr>
      </tbody>
    </table>
  </div>
);

If you want to remove the renderTD function you can create a new array of length a, but I guess it's not a very efficient method to do this.

function daysInCurrentMonth() {
  var now = new Date();
  return new Date(now.getFullYear(), now.getMonth() + 1, 0).getDate();
}
let a = daysInCurrentMonth();

return (
  <div>
    <table>
      <tbody>
        <tr>
          {[...Array(a).fill(0)].map((_, i) => (
            <td key={i}>{i + 1}</td>
          ))}
        </tr>
      </tbody>
    </table>
  </div>
);
Sign up to request clarification or add additional context in comments.

Comments

0

The code block inside your JSX does not result in any value.

Try replacing

 {() => {
    for(let i=1;i<=a;i++){
      <td>{i}</td>
    }
 }}

by something like:

Array(a).keys().map((i) => <td>{i-1}</td>)

There may be smarter ways than Array(a).keys() to generate the value range you need.

1 Comment

it show me an error ''TypeError: Array(...).keys(...).map is not a function"
0

Better you should use map().

Make sure you have your i as an array:

i.map(elem -=>  {
    return <td>elem</td>
})

1 Comment

but that will not works dynamically , i must initialize the i array like that : const i = [1,2,3, ........... ,31];

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.