I'm trying to build a weather application using openweathermap api. As you can see below in the code, I use a boolean state to check when the form is summitted so I can pass that value to the <Result>
component(which I checked with hard code and it works). I want the function changeCity
(in the App) to return the <Result>
component with the value of city passed and in the same time to change the cityEmpty
state. But there I got the problem when I pass that in the return() {(cityEmpty) ? changeCity() : null}
{(cityEmpty) ? changeCity() : null}
import React, {useState} from 'react';
import Result from "./components/Result";
import Search from "./components/Search";
import './App.css';
function App() {
const [city, setCity] = useState ("");
const [cityEmpty, setCityEmpty] = useState(false);
const changeCity = () => {
setCityEmpty(false);
return (<Result city={city}/>);
}
return (
<div className="App">
<Search city={city} setCity={setCity} cityEmpty={cityEmpty} setCityEmpty={setCityEmpty}
/>
{(cityEmpty) ? changeCity() : null}
</div>
);
}
export default App;
import React from "react"
function Search({city, setCity, cityEmpty, setCityEmpty}){
const handleInputChange = (e) => {
setCity(e.target.value);
}
const handleSumbit = (e) => {
e.preventDefault();
console.log(cityEmpty);
setCityEmpty(true);
console.log(cityEmpty);
setCity("");
}
return(
<div>
<form onSubmit={handleSumbit}>
<input
type="text"
placeholder="Insert city"
value={city}
onChange = {handleInputChange}
>
</input>
</form>
</div>
);
}
export default Search
You can't call a state update inside the render of a component. Remember that whenever state is updated, it will re render the component. This will cause an infinite loop in your component.
changeCity
is called changeCity
, setCityEmpty
is called Instead, consider checking if city
is empty in your handleInputChange
and calling setCityEmpty
inside that function.
EDIT: To clarify a function that returns a component is completely fine, this is all components are really. Functions (or in previous react versions: classes) returning other components.
you don't have to return JSX from function. In your case it is pretty straightforward to use.
import React, {useState} from 'react';
import Result from "./components/Result";
import Search from "./components/Search";
import './App.css';
function App() {
const [city, setCity] = useState ("");
const [cityEmpty, setCityEmpty] = useState(false);
return (
<div className="App">
<Search city={city} setCity={setCity} cityEmpty={cityEmpty} setCityEmpty={setCityEmpty}
/>
{cityEmpty && <Result city={city}/>}
</div>
);
}
export default App;
import React from "react"
function Search({city, setCity, cityEmpty, setCityEmpty}){
const handleInputChange = (e) => {
setCity(e.target.value);
}
const handleSumbit = (e) => {
e.preventDefault();
console.log(cityEmpty);
setCityEmpty(true);
console.log(cityEmpty);
setCity("");
}
return(
<div>
<form onSubmit={handleSumbit}>
<input
type="text"
placeholder="Insert city"
value={city}
onChange = {handleInputChange}
>
</input>
</form>
</div>
);
}
export default Search
Not sure what the problem you're seeing is but I noticed you're setting state inside of a render function, which is a bad pattern. Any state changes will trigger a re-rendering of the component and if you set state within a render function then you'd have an infinite loop of re-renderings (but.
Try removing setCityEmpty(false)
in changeCity
.
const changeCity = () => {
return (<Result city={city}/>);
}
So how would you update cityEmpty? It's not clear what the end goal is here. With more info, we can find a better implementation.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.