简体   繁体   中英

How to create Material-UI nested style object from array using map in React

I have some prop data that gets passed in like this

columns={
  [
    {
      name: "Fund Name",
      width: "40%"
    },
    {
      name: "Review Date",
      width: "20%"
    },
    {
      name: "Company Debt",
      width: "20%"
    },
    {
      name: "Alerts",
      width: "10%"
    }
  ];
}

I need it to look like this...

const localTheme = {
  overrides: {
    MUIDataTableHeadCell: {
      root: {
        "&:nth-child(1)": {
          width: "40%"
        },
        "&:nth-child(2)": {
          width: "20%"
        },
        "&:nth-child(3)": {
          width: "20%"
        },
        "&:nth-child(4)": {
          width: "10%"
        },
        "&:nth-child(5)": {
          width: "10%"
        }
      }
    }
  }
}

I am trying this...

let rowWidths = this.props.columns.map((item, key) => ({
  "&:nth-child(+key+)": {
    width: item.width
  }
}));

const localTheme = {
  overrides: {
    MUIDataTableHeadCell: {
      root: {
        rowWidths
      }
    }
  }
}

But this obviously doesn't work. Can someone please help.

Thanks

Use Object.fromEntries() to write it in one line

transforms a list of key-value pairs into an object.

  const root = Object.fromEntries(
    columns.map((x, idx) => [`&:nth-child(${idx + 1})`, { width: x.width }])
  );

Demo try it in-text:

 const columns = [ { name: "Fund Name", width: "40%" }, { name: "Review Date", width: "20%" }, { name: "Company Debt", width: "20%" }, { name: "Alerts", width: "10%" } ]; const root = Object.fromEntries( columns.map((x, idx) => [`&:nth-child(${idx + 1})`, { width: x.width }]) ); const localTheme = { overrides: { MUIDataTableHeadCell: { root: root } } } console.log(localTheme);

You can make use of Object.assign, spread syntax and the string literals to get the desired result

 let columns=[ { name: "Fund Name", width: "40%" }, { name: "Review Date", width: "20%" }, { name: "Company Debt", width: "20%" }, { name: "Alerts", width: "10%", }] let rowWidths = columns.map((item, key) => ({ [`&:nth-child(${key})`]: { width: item.width } }) ); const localTheme = { overrides: { MUIDataTableHeadCell: { root: Object.assign({}, ...rowWidths) } } } console.log(localTheme, rowWidths);

So basically what you want to do is convert '&:nth-child(+key+)' to '&:nth-child(1)' , '&:nth-child(2)' and so on right.

To use JS expression or dynamic string as keys in an object you need to use them within square brackets [] . I'm using reduce instead of map since the output must be objects instead of array

let rowWidths = this.props.columns.reduce((acc, item, key) =>
  ({
    ...acc,
    [`&:nth-child(${key})`]: {
       width: item.width
     }
   }),
   {}
);

And use spread operator to spread them open in localTheme

const localTheme = {
  overrides: {
    MUIDataTableHeadCell: {
      root: {
        ...rowWidths 
      }
   }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM