最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - ReactJS methods and useState stuff break into a separate file - Stack Overflow

programmeradmin0浏览0评论

I have a ponent called Invoice.js. This has more than 1000 lines of code. I do want to break a few methods and their relevant useState stuff to a separate file.

I have an array called items and API call to fill the array.

 const [items, setItems] = useState([]);

 // load items
  const loadItems = async () => {
    try {
      let items = await axios.get("/item");
      setItems(items.data);
    } catch (error) {
      setAlert({
        showAlert: true,
        severity: "error",
        message: "Customer loading failed!",
      });
    }
  };

Please note that I am calling this array in the useEffect hook.

// use effect hook
  useEffect(() => {
    //load active agents
    loadAgent();

    //load items
    loadItems();
  }, []);

I do want to break this whole thing into a separate file and just import the items array.

Another case is addItem method.

  const addItem = (e) => {
    // check this item already added
    const foundItem = initialValues.items.find((itm) => itm.id === item.id);

    if (foundItem) {
      setAlert({
        showAlert: true,
        severity: "error",
        message: "This item already added!",
      });
    } else {
      const originalItem = items.find((el) => el.id === item.id);
      const { id, description, size } = originalItem;
      const newEl = {
        id,
        description,
        size,
        unitPrice: Number(item.unitPrice).toFixed(2),
        qty: item.qty,
        amount: (Number(item.qty) * Number(item.unitPrice)).toFixed(2),
      };
      setInitialValues({
        ...initialValues,
        items: [...initialValues.items, newEl],
      });
    }
  };

In this case, this function depends on both items array and initialValues object.

How do I achieve this using React, with keeping mind if something went wrong inside these functions I need to fire the setAlert method in the Invocie.js ponent.

I have a ponent called Invoice.js. This has more than 1000 lines of code. I do want to break a few methods and their relevant useState stuff to a separate file.

I have an array called items and API call to fill the array.

 const [items, setItems] = useState([]);

 // load items
  const loadItems = async () => {
    try {
      let items = await axios.get("/item");
      setItems(items.data);
    } catch (error) {
      setAlert({
        showAlert: true,
        severity: "error",
        message: "Customer loading failed!",
      });
    }
  };

Please note that I am calling this array in the useEffect hook.

// use effect hook
  useEffect(() => {
    //load active agents
    loadAgent();

    //load items
    loadItems();
  }, []);

I do want to break this whole thing into a separate file and just import the items array.

Another case is addItem method.

  const addItem = (e) => {
    // check this item already added
    const foundItem = initialValues.items.find((itm) => itm.id === item.id);

    if (foundItem) {
      setAlert({
        showAlert: true,
        severity: "error",
        message: "This item already added!",
      });
    } else {
      const originalItem = items.find((el) => el.id === item.id);
      const { id, description, size } = originalItem;
      const newEl = {
        id,
        description,
        size,
        unitPrice: Number(item.unitPrice).toFixed(2),
        qty: item.qty,
        amount: (Number(item.qty) * Number(item.unitPrice)).toFixed(2),
      };
      setInitialValues({
        ...initialValues,
        items: [...initialValues.items, newEl],
      });
    }
  };

In this case, this function depends on both items array and initialValues object.

How do I achieve this using React, with keeping mind if something went wrong inside these functions I need to fire the setAlert method in the Invocie.js ponent.

Share Improve this question edited Oct 12, 2020 at 15:08 mkrieger1 23.6k7 gold badges64 silver badges82 bronze badges asked Oct 12, 2020 at 8:55 margherita pizzamargherita pizza 7,23729 gold badges103 silver badges178 bronze badges 1
  • Remember that hooks can only be used within ponents. You could probably split the Invoice ponent into smaller ponents where every ponent will be responsible for something else, i.e. list of items, total values, customer info etc. – szczocik Commented Oct 12, 2020 at 9:08
Add a ment  | 

3 Answers 3

Reset to default 4

You could write a custom hook, pass in all dependencies as parameters and return all the functions and states:

  function useItems({ setAlert }) {
     const [items, setItems] = useState([]);

     async function loadItems() { ... }
     function addItem(item) { ... }

     useEffect(() => { loadItems(); }, []);

     return { items, addItem };
  }

  // Then embed as
 function setAlert() { ... }
 const { items, addItem } = useItems({ setAlert });

The hook is then independent from the ponent, and can be moved into another file.

Basically what you need is custom hook.Something like this

const useItems = setAlert => {
  const [items, setItems] = useState([]);

  // load items
  const loadItems = async () => {
    try {
      const items = await axios.get("/item");
      setItems(items.data);
    } catch (error) {
      setAlert({
        showAlert : true,
        severity  : "error",
        message   : "Customer loading failed!",
      });
    }
  };

  return [items, loadItems];
};

And you call it on anywhere like this. As it was before

const [itemd, loadItems] = useItems(setAlert);

useEffect(() => {
  loadItems()
}, []);

I would say custom Hooks are the solutions you are looking for, to be exact on your use case -

You might want to create a custom hook useItems and transfer the code of useState and useEffect to that file and just write

const {data, error} = useItems();

Your useItems could be like

export default () => {
   const [items, setItems] = useState([]);
const [error, setError] = useState(null)
   useEffect(() => {
//your fetch code
}, []) 

return {data: items, error}
}

To make this generic what I did it, I create custom hooks for different types of network calls.

like usePost, useGet etc handling the different data trigger cases I had.

发布评论

评论列表(0)

  1. 暂无评论