Search code examples
reactjsuse-effectuse-state

react useState not re rendering


I have a pretty simple useEffect hook

const [tagsWithData, setTagsWithData] = useState([]);
useEffect(() => {
    ....
    const finalsTags = temp.map((item) => item.name);
    setTagsWithData(finalsTags);
 }, []);

Inside of return, I have condition to render the input tag

{tagsWithData.length !== 0 ? (
    <TagsInput
        selectedTags={selectedTags}
        tags={tagsWithData}
     />
      ) : (
      <TagsInput
     selectedTags={selectedTags}
     tags={tags}
     />
 )}

The above code always stays on 0 and it does not move to the else condition.

What am I making wrong here.

Thank you


Solution

  • Your useEffect is not being told to update. useEffect needs to be passed the value/dependencies that it needs to (trigger the) update on. Without it, the effect will only run once on (initial) component render

    const [tagsWithData, setTagsWithData] = useState([]);
    useEffect(() => {
        ....
        const finalsTags = temp.map((item) => item.name);
        setTagsWithData(finalsTags);
     }, [temp]);  // <--- add this
    

    Below is a small example illustrating the differences. Click on the button, and check out the output of both effectWithDep and effectWithoutDep. You'll notice only effectWithDep will update.

    // Get a hook function
    const { useState, useEffect } = React;
    
    const Example = ({title}) => {
      const [count, setCount] = useState(0);
      
      const [effectWithDep, setEffectWithDep] = useState(0); 
      const [effectWithoutDep, setEffectWithoutDep] = useState(0);
      
      useEffect(() => {
         setEffectWithDep(count)
      }, [count])
      
      useEffect(() => {
         setEffectWithoutDep(count)
      }, [])
    
      return (
        <div>
          <p>{title}</p>
          
          <p>effectWithDep: {effectWithDep}</p>
          
          <p>effectWithoutDep: {effectWithoutDep}</p>
          
          <button onClick={() => setCount(count + 1)}>
            Click me
          </button>
        </div>
      );
    };
    
    // Render it
    ReactDOM.render(
      <Example title="Example using Hooks:" />,
      document.getElementById("react")
    );
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
    <div id="react"></div>