如何使用自定义挂钩中的数据在useState中进行初始化?

时间:2019-09-10 05:51:58

标签: reactjs react-hooks

我正在学习React Hooks。 而且,我正在努力使用自定义钩子从服务器中获取初始化数据。

我认为我使用了错误的钩子。 我的代码在下面。

const useFetchLocation = () => {
    const [currentLocation, setCurrentLocation] = useState([]);

    const getCurrentLocation = (ignore) => {
         ...
    };

    useEffect(() => {
        let ignore = false;

        getCurrentLocation(ignore);
        return () => { ignore = true; }
    }, []);

    return {currentLocation};
};

const useFetch = (coords) => {
    console.log(coords);
    const [stores, setStores] = useState([]);

    const fetchData = (coords, ignore) => {
        axios.get(`${URL}`)
            .then(res => {
                if (!ignore) {
                    setStores(res.data.results);
                }
            })
            .catch(e => {
                console.log(e);
            });
    };

    useEffect(() => {
        let ignore = false;

        fetchData(ignore);
        return () => {
            ignore = true;
        };
    }, [coords]);

    return {stores};
}

const App = () => {
    const {currentLocation} = useFetchLocation();
    const {stores} = useFetch(currentLocation); // it doesn't know what currentLocation is.
...

很明显,它不能同步工作。 但是,我相信有正确的方法。 在这种情况下,我该怎么办? 如果您给我任何想法,我将不胜感激。 谢谢。

1 个答案:

答案 0 :(得分:0)

不确定所有ignore变量的含义,但是如果设置了coords,则可以检查效果。仅当设置coords时,您才应发出axios请求。

const useFetchLocation = () => {
  // Start out with null instead of an empty array, this makes is easier to check later on
  const [currentLocation, setCurrentLocation] = useState(null);

  const getCurrentLocation = () => {
    // Somehow figure out the current location and store it in the state
    setTimeout(() => {
      setCurrentLocation({ lat: 1, lng: 2 });
    }, 500);
  };

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

  return { currentLocation };
};

const useFetch = coords => {
  const [stores, setStores] = useState([]);

  const fetchData = coords => {
    console.log("make some HTTP request using coords:", coords);
    setTimeout(() => {
      console.log("pretending to receive data");
      setStores([{ id: 1, name: "Store 1" }]);
    }, 500);
  };

  useEffect(() => {
    /*
     * When the location is set from useFetchLocation the useFetch code is
     * also triggered again. The first time coords is null so the fetchData code
     * will not be executed. Then, when the coords is set to an actual object
     * containing coordinates, the fetchData code will execute.
     */
    if (coords) {
      fetchData(coords);
    }
  }, [coords]);

  return { stores };
};

function App() {
  const { currentLocation } = useFetchLocation();
  const { stores } = useFetch(currentLocation);
  return (
    <div className="App">
      <ul>
        {stores.map(store => (
          <li key={store.id}>{store.name}</li>
        ))}
      </ul>
    </div>
  );
}

工作中的沙箱(无评论)https://codesandbox.io/embed/eager-elion-0ki0v