skip to Main Content

I am attempting to update the color of the text in my function based on if the deadline has already passed or not. I want to call the function ‘ChangeStyle’ with each iteration of the mapping in order to do this for each specific value, but am running into the error about incorrect hook rendering.

When I was looking into the error online, most everyone was saying to put the conditions inside the useEffect, which I have done, and ensure that there aren’t any premature return statements which wasn’t a problem to begin with. I also attempted calling the useEffect within a custom hook which also didn’t fix the error. I also theorized that maybe I was setting the state to a value it was already equal to (like color is already ‘black’ and then I setColor(‘black’) again), so I attempted the line that is now commented out to see if that would work. Error persisted though I still think this might be the issue if I’m not putting that line in the right spot.

Any and all input is greatly appreciated!

    const [color, setColor] = useState('');

    function ChangeStyle(deadline) {
        var date = new Date();
        date = date.toISOString().substring(0,10);
        
        var color='';

        useEffect(()=> {
            
            //condition works
            if (deadline != null && deadline < date) {
                color = 'red';
            } else {
                color='black';
            }
        
            setColor(color);
            
        },[color]);

        return <></>;
    }



return (
        <div>
            {todos.map((todo,index)=>{
                return(
                    <div key = {index} class="task">

                        {/* the function with the error */}
                        {ChangeStyle(todo.date)}

                        <Popup class="detailedTask" trigger={
                             <button style={{color: color}}>
                                 {todo.title}<br></br>{todo.date} 
                             </button>} 
                             open={show} onOpen={openform} 
                             position="right center" nested modal
                        >

                            <button style={{color: color}}>{todo.title}<br></br>{todo.date}</button>
                        </ Popup>
                        
                        {/* {()=>setColor('')} this does NOT work*/}
                      
                    </div>
                    
                )
            })}

        </div>
)


2

Answers


  1. Chosen as BEST ANSWER

    So unfortunately the other suggestions didn't work because they caused some errors but I did find an alternative after being inspired by the conditional rendoring. I ended up getting rid of style entirely and instead put a condition inside of a class name that was connected to a css file. See below:

    CSS

    .red {
      color: red;
    }
    

    JSX

    return (
        <div>
            {todos.map((todo,index)=>{
                return(
                    <div key = {index} class="task">
    
                        <Popup class="detailedTask" trigger={
                             <button className={(todo.date != null && todo.date < 
                                new Date().toISOString().substring(0,10)) 
                                ? 'red' : null}>
                                 {todo.title}<br></br>{todo.date} 
                             </button>} 
                             open={show} onOpen={openform} 
                             position="right center" nested modal
                        >
    
                            <button style={{color: color}}>{todo.title}<br></br>{todo.date}</button>
                        </ Popup>
                      
                    </div>
                    
                )
            })}
    
        </div>
    )
    

  2. Well, first of all, this is not the way you want to use "useState" hooks
    i think you want to render all of the todo item, then check if the item dateline has passed. if so, then just use "Conditional rendering" or for this specific case "Conditional styling"

    just do it like this

    <button style={todo.date < new Date() && {color: 'red'}}>
    

    what this code does is determine if the todo.date is already passed if yes add {color: 'red'} to the button, otherwise nothing happen

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search