skip to Main Content

Is there a native way to add a style class name to a react element passed as a property WITHOUT using jQuery or any 3rd-party libraries.
The following example should demonstrate what I’m trying to do. Note, react class names are made up.

Edit: The point is to modify the class name of a react element that is passes as a property to the Books class! The Books class needs to modify the class name. Apparently, it does not have access to Authors class’s state to use within Authors class.

File authors.js

class Authors {
    render() {
        return (
            <ul>
                <li>John Doe</li>
                <li>Jane Doe</li>
            </ul>
        );
    }
}

File shelf.js

class Shelf {
    render() {
        return (
            <div>
                <Books authors={<Authors/>}/>
            </div>
        );
    }
}

File books.js

class Books {
    this.props.authors.addClass('style-class-name'); <- HERE

    render() {
        return (
            <div>
                {this.props.authors}
            </div>
        );
    }
}

2

Answers


  1. Potentially need more context, but in this kind of scenario, I would use state to dynamically add/remove a class. A basic example would be:

    const App = () => {
      const [dynamicClass, setDynamicClass] = useState("");
    
      return (
        <div className={`normalClass ${dynamicClass}`}>
          <button onClick={() => setDynamicClass("red")}>Red</button>
          <button onClick={() => setDynamicClass("green")}>Green</button>
          <button onClick={() => setDynamicClass("")}>Reset</button>
        </div>
      );
    };
    

    The state changes schedule a re-render, hence you end up with dynamic classes depending on the state. Could also pass the class in as a property, or however you want to inject it into the component.

    Login or Signup to reply.
  2. React elements do have an attribute called className. You can use that to set CSS classes to your component. You can pass static data (strings) or dynamic ones (basically calculated ones):

    
    <div className="fixedValue" />
    <div className={fromThisVariable} />
    

    Keep in mind, that you have to pass down your className, if you wrap native HTML elements in a component:

    class Books {
    
        render() {
            const {
               authors,
               // other represents all attributes, that are not 'authors'
               ...other
            }
    
    
            return (
                <div {...other}>
                    {this.props.authors}
                </div>
            );
        }
    }
    
    

    If you want to add data to your authors attribute (which I assume is an array), you could implement a thing like the following:

    let configuredAuthors = this.props.authors.map((author) => ({
        return {
            ...author,
            className: `${author.firstName}-${author.lastName}` 
        }
    }))
    

    Keep in mind, that either way, you have to manually assign this className property in your child components (I guess an Author component)

    To handle updates from a child component, use functions: https://reactjs.org/docs/faq-functions.html

    Full example:

    import React from "react";
    
    class Shelf extends React.Component {
      render() {
        const authors = [
          {
            firstName: "John",
            lastName: "Tolkien"
          },
          {
            firstName: "Stephen",
            lastName: "King"
          }
        ];
    
        return (
          <div>
            <Books authors={authors} />
          </div>
        );
      }
    }
    
    
    
    const Books = ({authors, ...other}) => {
    
      const [configuredAuthors, setAuthors] = React.useState(authors)
      const updateClassName = (authorIndex, newClassName) => {
        const newAuthors = [...configuredAuthors]
    
        newAuthors[authorIndex] = {
          ...configuredAuthors[authorIndex],
          className: newClassName
        }
    
        setAuthors(newAuthors)
      }
    
      
    
      return (
        <ul {...other}>
          {configuredAuthors.map((author, index) => {
            return <Author key={index} author={author} 
            index={index}
            updateClassName={updateClassName}
            />;
          })}
        </ul>
      );
    }
    
    
    const Author = ({ author, index, updateClassName, ...other }) => {
      const [count, setCount] = React.useState(0);
      
    
      return (
        <li className={author.className} {...other}>
          <span>{`${author.firstName} ${author.lastName}`}</span>
          <button
            onClick={() => {
              updateClassName(index, `author-${count}`);
              setCount(count + 1);
            }}
          >
            update Class ()
            {`current: ${author.className || '<none>'}`}
          </button>
        </li>
      );
    };
    
    export default function App() {
      return <Shelf />;
    }
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search