简体   繁体   English

添加 CSS style using className in Material UI component coming from dynamic json object in ReactJS

[英]Add CSS style using className in Material UI component coming from dynamic json object in ReactJS

I have a dynamic json object which contains a button element.我有一个包含按钮元素的动态 json object。 I am using createElement and material UI to render the object data.我正在使用 createElement 和材质 UI 来呈现 object 数据。

I wanted to apply customizable CSS using className in the button component, but I couldn't achieve it.我想在按钮组件中使用 className 应用可自定义的 CSS,但我无法实现。 So, how can I apply CSS in runtime to the material UI component?那么,如何在运行时将 CSS 应用到 Material UI 组件?

Here is my code snippet:这是我的代码片段:

import React, { useState } from "react";
import './App.css';
import { Button, Grid, Checkbox, TextField, Switch, Link } from '@mui/material';



const KeysToComponentMap = {
    button: Button,
    grid: Grid,
    checbox: Checkbox,
    text: TextField,
    switch: Switch,
    link: Link
};


const RenderCard = (props) => {



    const SampleData =
        [
            {
                "type": "button",
                "display": "RELEASE THE BATCH",
                "key": "RS",
                "class": "btn",
                "value": [
                    {
                        "type": "button",
                        "display": "CONFIRM AND SUBMIT",
                        "key": "key1",
                        "value": "post"
                    }
                ]
            },
            {
                "type": "button",
                "display": "RELEASE THE OBSERVATION",
                "key": "RO",
                "value": [
                    {
                        "type": "input",
                        "display": "Observation",
                        "key": "key8",
                        "value": "val1"
                    },
                    {
                        "type": "button",
                        "display": "Done",
                        "key": "key9",
                        "value": [
                            {
                                "type": "button",
                                "display": "CONFIRM AND SUBMIT",
                                "key": "key10",
                                "value": "post"
                            }
                        ]
                    }
                ]
            }
        ]

    }




    return (
        <>{

            
                {SampleData.map((item, index) => {
                    console.log(item.type);
                    console.log(item.class)
                    
                    if (typeof KeysToComponentMap[item.type] !== "undefined") {
                        
                        return (
                            React.createElement(
                                KeysToComponentMap[item.type],
                                {
                                    onClick: () => { onButtonHandler(item, item.key) },
                                    variant: "contained",
                                    type: "input",
                                    className: KeysToComponentMap[item.class],
                                    
                                },
                                
                                item.display &&
                                (typeof item.display === "string"
                                ? item.display
                                : item.value.map(c => ActivityDetail(c)))
                            ))
                            
                    }
                    
                })} 
                
        }
            
        </>)
}

export default RenderCard;

Original Question:原问题:

Your problem isn't that the className isn't being applied, it's that the value that you're trying to assign from KeysToComponentMap ( KeysToComponentMap[item.class] ) is returning undefined .您的问题不是没有应用className ,而是您尝试从KeysToComponentMap ( KeysToComponentMap[item.class] ) 分配的值返回undefined I had to modify your code, and add a class property to your Sample JSON, to get it to work so you may want to change it however you need it:我不得不修改您的代码,并向您的示例 JSON 添加一个class属性,以使其正常工作,因此您可能希望根据需要更改它:

{
  onClick: () => {
    onButtonHandler(item, item.key);
  },
  variant: "contained",
  type: "input",
  className: item.class // Changed from `className: KeysToComponentMap[item.class]`
},

Working Code Sandbox: https://codesandbox.io/s/classname-cjlqo?file=/demo.js工作代码沙箱: https://codesandbox.io/s/classname-cjlqo?file=/demo.js

Question from Comments:来自评论的问题:

in case if i want to pass style directly instead of classname then in what format should be style property be in sample JSON. I was passing style in json like: [{"style": "color: 'red'"}] but it is a wrong way that's why not working.如果我想直接传递样式而不是类名,那么样例 JSON 中的样式属性应该采用何种格式。我在 json 中传递样式,例如:[{"style": "color: 'red'"}] 但它是一种错误的方式,这就是为什么不工作。 So, what is the correct way?那么,正确的做法是什么?

Since you are using MUI 5, the correct prop to pass inline styles is sx .由于您使用的是 MUI 5,因此传递内联 styles 的正确道具是sx You may want to make your configuration a bit more flexible by just passing whatever additional properties each component might need straight through and spreading them into the component directly.您可能希望通过直接传递每个组件可能需要的任何附加属性并将它们直接传播到组件中来使您的配置更加灵活。 For example:例如:

// Sample config:
{
  type: "button",
  display: "RELEASE THE BATCH",
  key: "RS",
  className: "my-button",
  sx: { color: "blue" },
  value: [
    {
      type: "button",
      display: "CONFIRM AND SUBMIT",
      key: "key1",
      value: "post"
    }
  ]
},


// Renderer
    <>
      {SampleData.map(({ type, key, display, value, ...rest }, index) => {
        console.log(type);

        if (typeof KeysToComponentMap[type] !== "undefined") {
          return React.createElement(
            KeysToComponentMap[type],
            {
              onClick: () => {
                onButtonHandler(item, key);
              },
              variant: "contained",
              type: "input",
              ...rest
            },

            display &&
              (typeof display === "string"
                ? display
                : value.map((c) => ActivityDetail(c)))
          );
        }
      })}
    </>

Working example with className and style : https://codesandbox.io/s/style-e4inc?file=/demo.js使用classNamestyle的工作示例: https://codesandbox.io/s/style-e4inc?file=/demo.js

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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