Modifying a Nested Component with react-icons

As I work on creating a rating component that utilizes react-icons to display icons, I have encountered an interesting challenge. Currently, I am using the FaStarhalf icon which represents a pre-filled half star that can be flipped to give the appearance of half stars. While this solution serves its purpose well, I am seeking a more efficient way to indicate when a star is being selected. Unfortunately, the current version of react-icons lacks the capability to completely fill an icon like I desire. The FaRegStarHalf icon, another offering from react-icons, resembles a cut-out star but cannot be filled in.

This brings me to my inquiry: Is it feasible for the FaStarHalf component to dynamically change all instances of itself into their filled counterparts within the react-icons library upon being clicked? Can a component modify itself to become a different component?

Rater

import React, { useState } from 'react'
import { FaStarHalf } from 'react-icons/fa'

import './styles/Rater.css'

const Rater = ({ iconCount }) => {
    const [rating, setRating] = useState(null)
    const [hover, setHover] = useState(null)
    return (
        <div>
            {[...Array(iconCount), ...Array(iconCount)].map((icon, i) => {
                const value = (i + 1) / 2

                return (
                    <label>
                        <input
                            type='radio'
                            name='rating'
                            value={value}
                            onClick={() => {
                                console.log(`value => `, value)
                                return setRating(value)
                            }}
                        />
                        <div className='star-container'>
                            <div>
                                <FaStarHalf
                                    className={i % 2 ? 'star-left' : 'star'}
                                    color={value <= (hover || rating) ? '#ffc107' : '#e4e5e9'}
                                    onMouseEnter={() => setHover(value)}
                                    onMouseLeave={() => setHover(null)}
                                />
                            </div>
                        </div>
                    </label>
                )
            })}
        </div>
    )
}

export default Rater
FaHalfStar

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

FaRegHalfStar

https://i.sstatic.net/2GGl2.png

Answer №1

It can be challenging to provide a precise answer without actually seeing the data you are dealing with, but I will try to help. If your goal is to allow users to select a rating between 1 and 5 by clicking on stars and then display that rating using filled star icons, you can achieve this by utilizing the rating variable to determine whether to display the current rating or the user's selected rating.

One approach to implementing this functionality is to assign a specific icon name based on the rating value. For instance, if the user has set a rating, you can use the icon for a filled star; otherwise, you can show an icon for a half-filled star. This can be done by assigning a variable based on the condition:

const Star = rating ? 'FaStar' : 'FaHalfStar'

import React, { useState } from 'react'
import { FaStarHalf, FaStar } from 'react-icons/fa'

import './styles/Rater.css'

const Rater = ({ iconCount }) => {
    const [rating, setRating] = useState(null)
    const [hover, setHover] = useState(null)
    
    const Star = rating ? 'FaStar' : 'FaHalfStar'

return (
    <div>
        {[...Array(iconCount), ...Array(iconCount)].map((icon, i) => {
            const value = (i + 1) / 2              
            
            return (
                <label>
                    <input
                        type='radio'
                        name='rating'
                        value={value}
                        onClick={() => {
                            console.log(`value => `, value)
                            return setRating(value)
                        }}
                    />
                    <div className='star-container'>
                        <div>
                            <Star
                                className={i % 2 ? 'star-left' : 'star'}
                                color={value <= (hover || rating) ? '#ffc107' : '#e4e5e9'}
                                onMouseEnter={() => setHover(value)}
                                onMouseLeave={() => setHover(null)}
                            />
                        </div>
                    </div>
                </label>
            )
        })}
    </div>
)
}

export default Rater
FaHalfStar

Answer №2

I managed to solve the problem by adapting a code similar to what @CaseyC had used. Instead of focusing on using a full star, I needed to identify the corresponding Halfstar that was filled in.

import React, { useState } from 'react'
import { FaRegStarHalf, FaStarHalf } from 'react-icons/fa'

import './styles/Rater.css'

const Rater = ({ iconCount }) => {
    const [rating, setRating] = useState(null)
    const [hover, setHover] = useState(null)
    // determine which icons to display based on user rating
    const Star = rating ? FaStarHalf : FaRegStarHalf

    return (
        <div>
            {[...Array(iconCount), ...Array(iconCount)].map((icon, i) => {
                const value = (i + 1) / 2

                return (
                    <label>
                        <input
                            type='radio'
                            name='rating'
                            value={value}
                            onClick={() => {
                                console.log(`value => `, value)
                                return setRating(value)
                            }}
                        />
                        <div className='star-container'>
                            <div>
                                <Star
                                    className={i % 2 ? 'star-left' : 'star'}
                                    color={value <= (hover || rating) ? '#ffc107' : '#e4e5e9'}
                                    onMouseEnter={() => setHover(value)}
                                    onMouseLeave={() => setHover(null)}
                                />
                            </div>
                        </div>
                    </label>
                )
            })}
        </div>
    )
}

export default Rater

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Triggering animation with jQuery and CSS

I am working on a one-page site and I want to make a parallelogram disappear when a button is clicked for the next part. Currently, it is disappearing from right to left but I would like to change the direction to left to right. Additionally, I have a simi ...

Guide to creating a square-shaped Bootstrap popup box

Is it possible to change the shape of the bootstrap popup box from rectangular to square? I need it to be a square box. Any help would be greatly appreciated. Thank you in advance. For reference, here is an example: https://i.sstatic.net/APZNt.png < ...

Tips for creating a mock for a function that yields a JSX Element

I am facing a problem where I have a function that returns a JSX Element. Here is a snippet of the code: myFunction.jsx const myFunction = (props) => { // ... do something with props return <MyElement {...newProps} /> } // MyElement.j ...

What is the process of extracting data from JavaScript output using Mongoose?

Currently facing an issue with mongoose while working on a blog website and integrating quilljs. The problem arises from the output file in my JavaScript file that contains the configurations for my quill editor. var quill = new Quill('#editor&ap ...

Does the Apps Script parser JSON.parse() incorrectly remove leading zeros from string object keys?

I am facing an issue with my Apps Script Web App where JSON data is being manipulated when I try to parse it. Specifically, keys with leading zeros are being altered (e.g "0123" becomes "123") during the JSON.parse() function call. It seems like the functi ...

The window.onload function is ineffective when implemented on a mail client

Within my original webpage, there is a script that I have created: <script> var marcoemail="aaaaaa"; function pippo(){ document.getElementById("marcoemailid").innerHTML=marcoemail; } window.onload = pippo; </script> The issue a ...

Comparing a hexadecimal string from a buffer in JavaScript with Python

I am looking to output a hex escaped sequence string from a Buffer. For example: buffer = .... // => <Buffer d3 e9 52 18 4c e7 77 f7 d7> If I use the following: console.log(buffer.toString('hex')); The result is: d3e952184ce777f7d7 ...

A large canvas displaying a single optimized image

Hello, I have a large image on the canvas that measures around 10,000 pixels by 10,000 pixels. I am looking for zoom in/out functionality. Can you recommend what technology I should use? Should I consider splitting the image into smaller segments like Go ...

CSS rule for targeting an element that does not have any child elements

I have a variety of different elements that are structured similarly to the following.. <div id="hi"> <div class="head"> </div> <div class="footer"> </div> </div> ..however, some of these elements do no ...

Listening to LayersControl.Overlay checkbox clicks in React-Leaflet: A guide

My goal is to dynamically render overlay controls and bind a click event listener to the checkbox of each control in React. However, I am unsure how to provide a React ref to LayersControl or an onClick handler to LayersControl.Overlay. Is there a more eff ...

Dropdownmenu without borders

I'm having an issue with the dropdown menu on my website - there are no borders showing. I've tried fixing it myself with no luck, so I could really use some help. As a beginner in web development, I don't have much knowledge about these thi ...

Is the use of addEventListener("load",... creating an excessive number of XmlHttpRequests?

Consider a scenario where you have the following JavaScript code running in a Firefox plugin, aimed to execute an XmlHttpRequest on a page load: function my_fun(){ var xmlHttpConnection = new XMLHttpRequest(); xmlHttpConnection.open('GET', ...

Can the name of a React Component that is nested and inner be retrieved by invoking a function from one of its props?

I am currently working with this particular component: class DashboardPage extends Component { constructor(props) { super(props); this.state = { loading: true, shownPage: ActiveDeals, error: false, errorDetails: null, ...

"Learn the process of toggling the visibility of multiple objects by passing props from child components to parent components and

My approach to design is quite straightforward. I have a sidebar in child components (Aside.js) and a Main object that displays content (Main.js), all of which are used in ImportPage. In Aside, I have three buttons that I want to use to show and hide conte ...

Vue.JS enables the seamless addition of rows to a form on the fly

I am currently working on creating a dynamic form using Vue. The concept is that when the user clicks the add button, another row will appear for them to input data. However, I encountered an issue where initially only 1 row was set up, but when I added th ...

send a message to all clients using socket.io

I am having trouble figuring out how to broadcast a message from the client or another NodeJS file to all clients. While I was able to send messages to the server successfully, I am not able to reach every other client. Server code: var io = require(&ap ...

What is the solution for the error message "Module not found: Unable to locate 'p-queue' in 'node_modules@uppyprovider-viewslibProviderView'"?

Currently, I am running Node version v18.16.1 and in one of my recent projects, I encountered the following error: ./node_modules/@uppy/provider-views/lib/ProviderView/ProviderView.js Module not found: Can't resolve 'p-queue' in 'D:&bso ...

Flexslider optimized for mobile devices

I am currently using the Sparkling theme on a Wordpress website. This particular theme utilizes Flexslider within a div at the top of the page. Each slide featured in the slider includes an image, as well as a div containing a post title and excerpt. The ...

Despite granting Camera permission in the Android browser, the Zoom SDK's "ZoomVideo.getDevices()" method is still encountering a "DOMException: Permission denied" error

Currently troubleshooting why I am unable to list any devices on Android's Chrome browser when running the following code: ZoomVideo.getDevices() Upon reaching this line of code, my phone prompts for camera permission. After granting permission by p ...

Is there a way to make a React Component to update and navigate to a specific position using react-sound

Currently, I am in the process of constructing an audio player utilizing react-sound. One feature I aim to incorporate is the ability to return to a specific position within the audio track. At the moment, this is my approach: goToVeryCustomPosition() { ...