Search code examples
reactjsreact-reduxrenderuse-effect

useEffect doesn't want to update my display


I'm new here so take it easy :-)

I have a feeling I'm using useEffect incorrectly. Basically I have a few radio buttons on the page. When they are change/clicked I call a function that sets a variable call state to the selected item. The variable is also the trigger for the useEffect, so that fires and I perform some filter on an object variable called FilteredProjects.

In the console, when I log this out it has the correct values in them but the screen isn't updating with them, Is this because I'm not storing that value in state?

Here is the code section:(I've trimmed the code to the first use of the variable FilteredProject)

const [state,setstate] = useState(0)

let projectsList = useSelector(state=>state.projectReducer.projects)
let filteredProject = projectsList

  useEffect(() => {
    if(projectsList) {
      if(state == "All") {
        //show all statuses
        setfilteredProject(projectsList)
      } else{
        //single filter
        filteredProject = projectsList.filter(o => o.state === state);
      }
    }
}, [state])

function toggleStatus(e){
  console.log("state changed");
  setstate(e.value)
}


    return (
      <div className="px-2 py-4 ">
        <div className="card h-fit my-4 lg:w-12/12">
        <div className='form-check form-check-inline'><input className='form-check-input appearance-none h-4 w-4 border border-gray-300 rounded-sm bg-white checked:bg-blue-600 checked:border-blue-600 focus:outline-none transition duration-200 mt-1 align-top bg-no-repeat bg-center bg-contain float-left mr-2 cursor-pointer' name='status' type='radio' id='status' onClick={(e)=>toggleStatus(e.target)} value='All' defaultChecked={true}></input><label className='form-check-label inline-block text-gray-800 font-normal mr-2' ><b>All Statuses</b> </label></div>
        <div className='form-check form-check-inline'><input className='form-check-input appearance-none h-4 w-4 border border-gray-300 rounded-sm bg-white checked:bg-blue-600 checked:border-blue-600 focus:outline-none transition duration-200 mt-1 align-top bg-no-repeat bg-center bg-contain float-left mr-2 cursor-pointer' name='status' type='radio' id='status' onClick={(e)=>toggleStatus(e.target)} value='Fundraising' defaultChecked={false}></input><label className='form-check-label inline-block text-gray-800 font-normal mr-2' >Fundrasing </label></div>
        <div className='form-check form-check-inline'><input className='form-check-input appearance-none h-4 w-4 border border-gray-300 rounded-sm bg-white checked:bg-blue-600 checked:border-blue-600 focus:outline-none transition duration-200 mt-1 align-top bg-no-repeat bg-center bg-contain float-left mr-2 cursor-pointer' name='status' type='radio' id='status' onClick={(e)=>toggleStatus(e.target)} value='Successful' defaultChecked={false}></input><label className='form-check-label inline-block text-gray-800 font-normal mr-2' >Successful </label></div>
        <div className='form-check form-check-inline'><input className='form-check-input appearance-none h-4 w-4 border border-gray-300 rounded-sm bg-white checked:bg-blue-600 checked:border-blue-600 focus:outline-none transition duration-200 mt-1 align-top bg-no-repeat bg-center bg-contain float-left mr-2 cursor-pointer' name='status' type='radio' id='status' onClick={(e)=>toggleStatus(e.target)} value='Expired' defaultChecked={false}></input><label className='form-check-label inline-block text-gray-800 font-normal mr-2' >Expired </label></div>
        </div>
        <div className=" my-2 lg:my-0 lg:mx-2 grid sm:grid-cols-3 sm:gap-2 grid-cols-1">
          {filteredProject.....

Solution

  • This is worked for me like this, You need to update the state.
    
    const [radioValue, setRadioValue] = useState("male");
    const [data, setData] = useState("");
    
    const handleChange = (e) => {
     console.log(e.target.value);
     setRadioValue(e.target.value);
    };
    
    useEffect(() => {
    if (radioValue === "male") {
      setData("This is Male");
    } else {
      setData("This is FeMale");
    }
    }, [radioValue]);
    
    return (
    <div className="App">
      Male
      <input
        name="gender"
        type="radio"
        value="male"
        defaultChecked
        onChange={handleChange}
      />
      Female
      <input
        name="gender"
        type="radio"
        value="female"
        onChange={handleChange}
      />
      <div>
        <h3>{data}</h3>
      </div>
    </div>
    )