user3685525
user3685525

Reputation: 33

How to re-render react component depends on a file?

I have a file that stores an array of objects. I have a component that fetches data from this file then render the list. The file could be updated somewhere else, I need the component to be updated if the file is modified. I have following code example

const header = () => {
  const [list, setList] = useState([]);
  
  // fetch 
  useEffect(() => {
    const loadList = async () => {
      const tempList = await getList("/getlist"); // get call to fetch data from file
      setList(tempList);
    };
    loadList ();
  }, [list]);

  // function to render content
  const renderList = () => {
    return list.map(obj => (
      <div key={obj.name}>
        {obj.name}
      </div>
    ));
  };
  
  return (
    <div>{renderList()}</div>
  )
}

// get call
router.get('/getlist', 
  asyncWrapper(async (req, res) => {
    const result = await getList();
    res.status(200).json(result).end();
  })
);

const getList= async () => {
  const list = JSON.parse(await fs.readFile(listPath));
  return list;
}

Code has been simplified. If I remove the list from useEffect, then it will only render once and will never update unless I refresh the page. If I include list there, loadList() will get called constantly, and component will get re-rendered again and again. This is not the behavior I want. I am just wondering without making header component async component, how do I only re-render this component when the file is changed?

Thank you very much.

Upvotes: 0

Views: 298

Answers (1)

Quentin
Quentin

Reputation: 943561

There are two approaches you can take to this:

Polling

Request the URL on an interval, and clear it when the component is unmounted.

Replace loadList () with:

const interval = setInterval(loadList, 60000); // Adjust interval as desired
return () => clearInterval(interval)

Make sure the cache control headers set in the response to /getlist don't stop the browser from noticing updates.

Server push

Rip out your current code to get the data and replace it with something using websockets, possibly via Socket.IO. (There are plenty of tutorials for using Socket.io with React that can be found with Google, but its rather too involved to be part of a SO answer).

Upvotes: 1

Related Questions