0

I have a context.js as follows and so far the data is hardcoded (latitude and longitude) as well as initial weather values saved as objects in the same format I will receive from the server. I for now have an input box, this will be changed to Google places eventually but I just wanted the functionality working for now.

How can i get the input from the form back to the context to run the fetch request again on the form submit?

The server and the the axios request both work perfect.

My current context.js which is provided in index.js wrapping everything

const AppProivider = ({ children }) => {
  const [loading, setLoading] = useState(false);
  const [latitude, setLatitude] = useState(54.978252);
  const [longitude, setLongitude] = useState(-1.61778);
  const [current, setCurrent] = useState(currentx);
  const [hourly, setHourly] = useState(hourlyx);
  const [future, setFuture] = useState(futurex);

  const fetchWeather = useCallback(async () => {
    setLoading(true);
    try {
      const response = await axios.get("http://localhost:8000/weather", {
        params: { latitude, longitude },
      });

      const { current, hourly, future } = await response.data;
      if (current && hourly && future) {
        setCurrent(current);
        setHourly(hourly);
        setFuture(future);
      } else {
        setCurrent(currentx);
        setFuture(hourlyx);
        setHourly(futurex);
      }
      setLoading(false);
    } catch (error) {
      setLoading(false);
      console.log(error);
      return "There was a problem fetching the weather information, please try again";
    }
  }, [latitude, longitude]);

  useEffect(() => {
    fetchWeather();
  }, [latitude, longitude, fetchWeather]);

  return (
    <AppContext.Provider
      value={{
        loading,
        current,
        future,
        hourly,
        setLongitude,
        setLatitude,
      }}
    >
      {children}
    </AppContext.Provider>
  );
};

export const useGlobalContext = () => {
  return useContext(AppContext);
};

export { AppContext, AppProivider };

My Current, very basic, App.js to gather the information

import { useGlobalContext } from "../../context";

const App = () => {
  const { current, hourly, future, setLatitude } = useGlobalContext();
  const [lat, setLat] = useState(1);

  const handleChange = (e) => {
    e.preventDefault();
    setLatitude(lat);
    console.log(current);
  };

  return (
    <div>
      <form onSubmit={handleChange}>
        <input type="number" onChange={(e) => setLat(e.target.value)}></input>
        <input type="submit"></input>
      </form>
    </div>
  );
};

export default App;
Mario Petrovic
  • 7,500
  • 14
  • 42
  • 62
Dan Wilstrop
  • 355
  • 1
  • 4
  • 12

2 Answers2

0

if you need to change context, you should use useState and put inside the context state and setState

const App = () => {

let [state,setState] = useState({value: 1, value: 2})

   <AppContext.Provider value={{state,setState}}>
        <YourComponent />
    </AppContext.Provider>
}

now all your components are familiar with state and all of them can change the state too, you only need to take that function from context and use when you need

let {state,setState} = useContext(AppContext);
n1koloza
  • 539
  • 5
  • 11
  • I don’t follow? I have states in the context and pass down setState to this component? – Dan Wilstrop Apr 01 '21 at 10:56
  • Thank you but I am doing this. My whole component is wrapped in the context provider in index.js and my app component is destructuring the setState (in this case setLatitude) from the props along with the values. I can access the values so I can also access the setState function. When I update the set state function in App I want it to call the fetchWeather function in my context and update the states in context too which should work with the code in context.js – Dan Wilstrop Apr 01 '21 at 12:13
  • Im trying to do the same thing..I found some more detailed docs in the advanced section of react native hooks this helped me alot: https://reactjs.org/docs/context.html#updating-context-from-a-nested-component – Matt Laszcz May 16 '22 at 18:30
0

I have solved this myself with a simple error I had made. The functionality was fine it was a typo/param error from me. In context.js I changed

const response = await axios.get('http://localhost:8000/weather', {
                params: { latitude, longitude }
            })

To this

const response = await axios.get('http://localhost:8000/weather', {
                params: { lat: latitude, lon: longitude }
            })

As my server has code as below and was expecting different query params to what I had provided

const { lat, lon } = req.query
Dan Wilstrop
  • 355
  • 1
  • 4
  • 12