How to get data from form in custom hook? I want to call useSearch hook in SearchProducts component and pass the submitted data. Is there any better solution for this?
function useSearch() {
const submitHandle = (event) => {
event.preventDefault();
let data = [];
const elements = event.target.childNodes;
elements.forEach((element) => {
data[element.name] = element.value;
element.value = "";
});
// I need data from form here.
console.log(data);
};
return {
onSubmit: submitHandle,
};
}
export default function SearchProducts() {
const search = useSearch();
return (
<Container>
<Form {...search}>
<Input name="searchInput" />
<SearchButton type="submit">search</SearchButton>
</Form>
</Container>
);
}
export default function Input({ type, name }) {
const input = useInput("");
return <InputField type={type} name={name} {...input} />;
}
function useInput(initialValue) {
const [value, setValue] = useState(initialValue);
const handleChange = (event) => {
if (value === false) {
setValue(true);
}
setValue(event.target.value);
};
return {
value: value,
onChange: handleChange,
};
}
Related
I am making a website in which I am able to send notifications to all the users but there is a problem, it says
Notification.requestPermission() is not a function
Here is my code:
import React, { useState } from "react";
const Notification = () => {
const [input, setInput] = useState("");
const handleInput = (e) => {
e.preventDefault();
setInput(e.target.value);
};
const sendNotification = () => {
Notification.requestPermission().then((perm) => {
if (perm === "granted") {
new Notification(input, {
body: "Go check it out!",
});
}
});
};
return (
<>
<input type="text" value={input} onChange={handleInput} />
<button onClick={sendNotification}>Send</button>
</>
);
};
export default Notification;
I am using react
Thank You in advance!
How can I submit all of the typed data in MDEditor in my react app ? I have tried the below way to submit, but i am not getting the whole types in data as string, could someone please advise me ?
import MDEditor from '#uiw/react-md-editor';
const [value, setValue] = React.useState("**Create a new blog**");
const handleChange = (value) => {
// Updating the state here...
setValue(value);
const fetchData = async (value) => {
try{
const res = await axios.post(`${appURL}/service/createBlog`, {value });
if (res.data.success) {
// do rest of the
}
else {
}
} catch (e){
console.log(e);
}
}
fetchData();
}
<div className='container'>
<MDEditor
className='reactEditorArea'
value={value}
onChange={handleChange}
/>
</div>
Your fetchData has property value but you call it without value, fetchData().
To-BE
const handleChange = (value) => {
// ...
fetchData(value);
}
I'm currently working on a project to implement a website to check the weather forecast.
I'm trying to get the value from the input field and when I click the submit button, this value should be set to cityName. What do I have to change in order to make this work?
import { useState, useEffect } from "react"
export function WeatherInfo() {
const token: string = '7ebe7c2a03cd48c090a193437'
async function getCurrentWeather(cityName: string): Promise<any> {
const response = await fetch(`http://api.weatherapi.com/v1/current.json?key=${token}&q=${cityName}`)
const data = await response.json()
console.log(data)
return data
}
const [cityName, setCityName]: any = useState('')
const [cityWeather, setCityWeather] = useState({})
const [value, setValue] = useState('')
const handleChange = (event: any) => {
setValue(event.target.value)
}
const handleSubmit = (event: any) => {
event.preventDefault()
setCityName(value)
}
useEffect(() => {
async function fetchData() {
const cityWeather = await getCurrentWeather(cityName)
}
fetchData()
})
return (
<div >
<form onSubmit={handleSubmit}>
<input onChange={handleChange} placeholder="Type here" />
<button>Search</button>
</form>
</div>
);
}
You should add a dependency array to your effect hook so that it triggers whenever cityName changes.
Updating the cityWeather state should only be done via the setCityWeather function.
useEffect(() => {
if (cityName) { // only fetch when you've got a value
getCurrentWeather(cityName).then(setCityWeather);
}
}, [cityName]);
You should also try to use as few any types as possible, preferably none
// define stand-alone functions outside your components
// eg weather-api.ts
const token = "your-api-key";
export interface CurrentWeather {
temp_c: number;
feelslike_c: number;
// etc
}
export async function getCurrentWeather(
cityName: string
): Promise<CurrentWeather> {
// safely encode URL query params
const params = new URLSearchParams({
key: token,
q: cityName,
});
const response = await fetch(
`http://api.weatherapi.com/v1/current.json?${params}`
);
// don't forget to check for errors
if (!response.ok) {
throw response;
}
return response.json(); // will be cast to the `CurrentWeather` type
}
import { useState, useEffect, FormEventHandler } from "react";
import { getCurrentWeather, CurrentWeather } from "./weather-api";
export function WeatherInfo() {
const [cityName, setCityName] = useState("");
const [cityWeather, setCityWeather] = useState<CurrentWeather>(); // default undefined
const [value, setValue] = useState("");
useEffect(() => {
getCurrentWeather(cityName).then(setCityWeather).catch(console.error);
}, [cityName]);
const handleSubmit: FormEventHandler<HTMLFormElement> = (event) => {
event.preventDefault();
setCityName(value);
};
return (
<div>
{cityWeather && (
<p>
The current temperature in {cityName} is {cityWeather.temp_c} °C
</p>
)}
<form onSubmit={handleSubmit}>
<input
onChange={(e) => setValue(e.target.value)}
placeholder="Type here"
/>
<button>Search</button>
</form>
</div>
);
}
I am trying to update the database. So I have an input field that is disabled as default. So when you click, editing is enabled and when you click outside of the input field, it gets disabled again. What I am trying to do is update when you click outside of the input field. So, my input is like this:
const InputPrice = ({ mainPricePosts, handleChange }) => {
const [disabled, setDisabled] = useState(true);
const [priceValue, setPriceValue] = useState(mainPricePosts);
function handleClick() {
if (disabled === true) {
setDisabled(false);
}
}
return (
<>
<Form.Control
type="text"
className="price_coefficient_input"
value={priceValue}
onBlur={() => {
setDisabled(true);
handleChange(priceValue);
}}
onChange={handleChange(mainPricePosts)}
readOnly={disabled}
onClick={handleClick}
/>
</>
);
};
InputPrice.propTypes = {
mainPricePosts: PropTypes.object.isRequired,
handleChange: PropTypes.func.isRequired,
};
export default InputPrice;
And this is how I am trying to update but I am not sure if I am doing right to get the value from the input field:
const [updatePosts, setUpdatePosts] = useState([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(false);
const [show, setShow] = useState(false);
const [showError, setShowError] = useState(false);
const handleClose = () => setShow(false);
const handleCloseError = () => setShowError(false);
const fetchIndividualPosts = async ({ value, post: { mainPricePosts, key } = {} }) => {
console.log(value);
try {
setLoading(true);
const res = await Axios({
method: "POST",
url: `url`,
headers: {
"content-Type": "application/json",
},
data: {
updated_parameter: ["main_price", "small_car", key],
updated_value: value,
},
});
if (res.status === 200) {
setUpdatePosts(res.data);
}
setLoading(false);
} catch (err) {
console.log(err.response.status);
setError(err.response.data.error);
setLoading(false);
}
};
const handleChange = (mainPricePosts) => (e) => {
fetchIndividualPosts({ mainPricePosts, value: e.target.value });
};
This is also the curl how I can update the data:
curl -L -i -H "Content-Type: application/json" -X POST -d '{
"updated_parameter":["100"],
"updated_value":"0.044"
}' $ip''
so updated_value should be the updated input (the value after, outside is clicked)
100, should be the key of the input value.
Hope it is clear and you can help me about this problem.
Thanks for your help beforehand.
There are many ways you can achieve what you need, but I would use following approach.
In your InputPrice component on onBlur event I would disable input by calling setDisabled(true) and then use useEffect hook to call handleChange callback if new price value and original price values are different. Because you are calling setDisabled(true), you're actually re-rendering your InputPrice component and therefore not executing handleChange callback.
Checkout code below.
const InputPrice = ({ mainPricePosts, handleChange }) => {
const [disabled, setDisabled] = useState(true);
const [priceValue, setPriceValue] = useState(mainPricePosts);
function handleClick() {
if (disabled === true) {
setDisabled(false);
}
}
useEffect(() => {
let callUpdateCallback = false;
if (priceValue !== mainPricePosts) callUpdateCallback = true;
if (disabled && callUpdateCallback) handleChange(priceValue);
}, [disabled, priceValue, handleChange, mainPricePosts]);
return (
<>
<Form.Control
type="text"
className="price_coefficient_input"
value={priceValue}
onBlur={setDisabled(true)}
onChange={(e) => setPriceValue(e.target.value)}
readOnly={disabled}
onClick={handleClick}
/>
</>
);
};
InputPrice.propTypes = {
mainPricePosts: PropTypes.object.isRequired,
handleChange: PropTypes.func.isRequired,
};
export default InputPrice;
You call this component like this
import React from "react";
import ReactDOM from "react-dom";
import InputPrice from "./InputPrice";
function App() {
const handleChange = (e) => {
console.log("app handle change", e);
// You can call your fetch here...
};
return (
<div>
<InputPrice mainPricePosts="500" handleChange={handleChange} />
</div>
);
}
ReactDOM.render(<App />, document.querySelector("#root"));
Additionally there codesandbox that used to debug it, so if you need more details you can find it on the link below.
https://codesandbox.io/s/reactjs-playground-forked-8vwe2?file=/src/index.js:0-364
function DayOne() {
const [country, setCountry] = useState("");
const url = `${process.env.REACT_APP_BASE_URL}/dayone/all/total/country/${country}`;
const { data, error } = useSWR(url, fetcher);
let value = useRef("");
const onClick = async (e: React.ChangeEvent<HTMLInputElement>) => {
e.preventDefault();
return setCountry(value.current);
};
const onChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
e.preventDefault();
value.current = e.target.value;
};
let index = 1;
if (error) return <div>failed to load</div>;
if (!data) return <Loading />;
const { name } = data;
return (
<div>
{console.log(data)}
<ContainerComp>
<NavBar />
{console.log(country)}
<InputCountryForm myRef={value} onChange={onChange} onClick={onClick} />
<div>{country}</div>
{name &&
name.map((n: IDayOne) => {
<CustomCard icon={""} title={country} value={n.Active} />;
})}
</ContainerComp>
</div>
);
}
export default DayOne;
the fetcher
export const fetcher = (url: string) => fetch(url).then((res) => res.json());
Im trying to display a card list with values coming after picking a country a submitting to the endpoint. How can i improve this and actually make it work ?