React: Fetch Data onSubmit, not on onChange - javascript

I got this code working pretty much how I want it. However, it's fetching & display data after each keystroke. I only want it to fetch once, when I hit submit.
Also, if there's anything i'm doing that's not "best practice" please let me know so I don't make silly mistakes in the future.
import React, { useEffect, useState } from "react";
export default function App() {
const [data, setData] = useState(null);
const [query, setQuery] = useState("");
useEffect(() => {
if (!query) return;
async function fetchData() {
const response = await fetch(
`https://www.omdbapi.com/?apikey=2e8b5857&s=${query}`
);
const data = await response.json();
const results = data.Search;
setData(results);
}
fetchData();
}, [query]);
const handleSubmit = (e) => {
e.preventDefault();
setQuery(query);
};
return (
<div
style={{
margin: 20,
}}
>
<form onSubmit={handleSubmit}>
<br />
<label>
Input Movie:{" "}
<input
type="text"
placeholder="ex. Harry Potter"
value={query}
onChange={(e) => {
setQuery(e.target.value);
}}
/>
</label>
<input type="submit" value="Submit" onClick={() => setQuery} />
</form>
{data &&
data.map((movie) => (
<div key={movie.imdbID}>
<h1>{movie.Title}</h1>
<h4>
{movie.Year} | {movie.imdbID}
</h4>
<img alt={movie.imdbID} src={`${movie.Poster}`} />
</div>
))}
</div>
);
}

Since you only want it after submit, you can skip the useEffect with [query] and just copy the same logic inside your handleSubmit like so :-
import React, { useEffect, useState } from "react";
export default function App() {
const [data, setData] = useState(null);
const [query, setQuery] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
if (!query) return;
async function fetchData() {
const response = await fetch(
`https://www.omdbapi.com/?apikey=2e8b5857&s=${query}`
);
const data = await response.json();
const results = data.Search;
setData(results);
}
fetchData();
};
return (
<div
style={{
margin: 20,
}}
>
<form onSubmit={handleSubmit}>
<br />
<label>
Input Movie:{" "}
<input
type="text"
placeholder="ex. Harry Potter"
value={query}
onChange={(e) => {
setQuery(e.target.value);
}}
/>
</label>
<input type="submit" value="Submit"/>
</form>
{data &&
data.map((movie) => (
<div key={movie.imdbID}>
<h1>{movie.Title}</h1>
<h4>
{movie.Year} | {movie.imdbID}
</h4>
<img alt={movie.imdbID} src={`${movie.Poster}`} />
</div>
))}
</div>
);
}
Here's the codesandbox :-

Pass the code that is inside the useEffect, that is, the fetch function, inside the submit function. leaving useEffect unused

Related

Next.js trying to push data from input value into json, but onSubmit doesn't work at all

I'm trying to put input value into json file, but submit button doesn't work, can you help me with it?
import PcosData from "/data/pcos.json";
import {useEffect} from "react";
import { useState } from "react";
export default function adminPcos() {
// const CreateMePanel = () => {
const [title, setTitle] = useState(PcosData["pcos-first"].title);
const [time, setTime] = useState(PcosData["pcos-first"].time);
const handleSubmit = (e) => {
PcosData["pcos-first"].title = title;
PcosData["pcos-first"].time = time;
}
return (
<div>
<h1>hello world</h1>
{PcosData["pcos-first"].map((pcosdata) => (
<form onSubmit={handleSubmit} key={ pcosdata.id } method="post">
<input type="text" name={title} defaultValue={pcosdata.title} onChange={(e) => setTitle({text: e.target.value})}/>
<input type="text" name={time} defaultValue={pcosdata.time} onChange={(e) => setTime({text: e.target.value})}/>
<input type="submit" value="submit"/>
</form>
))}
</div>
)
}
i checked all of the functions, variables, but didn't find any errors

How to display Pokemon image in react js?

I am new in react JS technology , and I got a assignment from my job to display Pokemon name and image , I displayed name but I am Failed with displaying image of Pokemon, Can anyone help me to display image of pokemon. I f you have any query regarding my question please free feel to ask me.
import React, { useEffect, useState } from "react";
import Axios from "axios";
const Pokemonapi = () => {
const [text, setText] = useState("");
const [data, setData] = useState([]);
const Search = () => {
if (text == "") {
alert("Please Enter a name to be search");
} else {
searchPokemon();
setText("");
}
};
const searchPokemon = async () => {
const response = await Axios.get(
`https://pokeapi.co/api/v2/pokemon/${text}`
);
// const getdata = await response.json();
setData(response.data.results);
console.log(response);
};
useEffect(() => {
searchPokemon();
}, []);
return (
<div>
<div className="container-fluid jumbotron">
<div className="input-group mb-3">
<input
type="text"
className="form-control shadow-none"
placeholder="Search Pokemon"
value={text}
onChange={(e) => setText(e.target.value)}
/>
<div className="input-group-append">
<span
className="input-group-text"
id="basic-addon2"
onClick={Search}
>
Search
</span>
</div>
</div>
</div>
{data.map((dat, index) => {
return (
<div key={index}>
<h2>{dat.name}</h2>
<img src={dat.sprites.other.dream_world.front_default} />
</div>
);
})}
</div>
);
};
export default Pokemonapi;
It depends on what that api is returning , if it returns the url of the image , you can use
<img src={dat.sprites.other.dream_world.front_default} />, assuming that
front_default=url but if it returns a base64 encode of the image , then you need to use
<img src=`data:image/png;base64,${dat.sprites.other.dream_world.front_default}` />

How to show error if client did not click check, but with not default value

I am trying to show error message if client did not click checkbox, but it shows the error message by default.
How do I manage to show it only after submission?
const InputForm=()=>{
const [value ,setValue] = useState("");
const [check,setCheck] = useState(null)
const getValue=(e)=>{
setValue(e.target.value);
}
const getCheck=(e)=>{
setCheck(e.target.checked);
}
const handleSubmit=(e)=>{
e.preventDefault();
const emailValidator =/^\w+([\.-]?\w+)*#\w+([\.-]?\w+)*(\.\w{2,3})+$/
if (value.match(emailValidator)) {
console.log("Valid");
}else{
console.log("Invalid");
}
};
return(
<form className="inputForm" onSubmit={handleSubmit}>
<div className="tos" >
<label className="container">
<span>I agree to <strong>terms of service</strong></span>
<input type="checkbox" onChange={getCheck}/>
<span className="checkmark" ></span>
</label>
<p style={check?{display:"none"}:{display:"block",color:"red"}}>You must accept the terms and conditions</p>
</div>
<Footer/>
</form>
)
};
import { useEffect, useState } from "react";
export default function App() {
const [checked, setChecked] = useState(null);
const [error, setError] = useState(false);
useEffect(() => {
checked && setError(false);
}, [checked, setError]);
const handleSubmit = (e) => {
e.preventDefault();
if (!checked) {
setError(true);
} else {
// do what you want
}
};
return (
<form className="inputForm" onSubmit={handleSubmit}>
<div className="tos">
<label className="container">
<span>
I agree to <strong>terms of service</strong>
</span>
<input
type="checkbox"
onChange={(e) => setChecked(e.target.checked)}
/>
<span className="checkmark"></span>
</label>
{error && (
<p style={{ color: "red" }}>
You must accept the terms and conditions
</p>
)}
</div>
<button type="submit">submit</button>
</form>
);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Here is a solution :
https://codesandbox.io/s/crimson-field-m6j5h?file=/src/App.js
You should have a separate state for the error and render the message only if that state is truthy.
That state should be set when calling you handleSubmit function.
To remove the error message when the checkbox is checked, you can listen to it in a useEffect hook.

Login page issues while using react js and Django api

I am creating a simple login page using react js and Django api. I am able to login but unable to go to my dashboard as it is throwing error like "Unhandled Rejection (TypeError): Cannot read property 'status' of undefined"
I am using Visual Studio Code
The full code is as below:
Login.js
import React, { useState } from 'react';
import axios from 'axios';
import { setUserSession } from './Utils/Common';
function Login(props) {
const [loading, setLoading] = useState(false);
const username = useFormInput('');
const password = useFormInput('');
const [error, setError] = useState(null);
// handle button click of login form
const handleLogin = () => {
setError(null);
setLoading(true);
axios.post('http://localhost:8000/account/user/signin', { mobile_number: username.value,
password: password.value }).then(response => {
setLoading(false);
setUserSession(response.data.token, response.data.user);
props.history.push('/dashboard');
}).catch(error => {
setLoading(false);
if (error.response.status === undefined) setError(error.response.data.message);
else setError("Something went wrong. Please try again later.");
});
}
return (
<div>
Login<br /><br />
<div>
Username<br />
<input type="text" {...username} autoComplete="new-password" />
</div>
<div style={{ marginTop: 10 }}>
Password<br />
<input type="password" {...password} autoComplete="new-password" />
</div>
{error && <><small style={{ color: 'red' }}>{error}</small><br /></>}<br />
<input type="button" value={loading ? 'Loading...' : 'Login'} onClick={handleLogin}
disabled={loading} /><br />
</div>
);
}
const useFormInput = initialValue => {
const [value, setValue] = useState(initialValue);
const handleChange = e => {
setValue(e.target.value);
}
return {
value,
onChange: handleChange
}
}
export default Login;
Dashboard.js
import React from 'react';
import { getUser, removeUserSession } from './Utils/Common';
function Dashboard(props) {
const user = getUser();
//handle click event of logout button
const handleLogout = () => {
removeUserSession();
props.history.push('/login');
}
return (
<div>
Welcome {user.name}!<br /><br />
<input type="button" onClick={handleLogout} value="Logout" />
</div>
);
}
export default Dashboard;

Using React hooks for the first time and ran into an issue

I am using react for the first time in months and hooks for the first time ever. So far I love it, but I ran into an issue that has blocked me for hours now.
I have a component that looks like this:
import React, { useState } from "react";
import ReactModal from "react-modal";
import { useModal } from "react-modal-hook";
import styled from 'styled-components';
export function SearchImageForm(props) {
const [query, setQuery] = useState("");
const [images, setImages] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
fetch(`myurl&q=${query}`)
.then((response) => {
return response.json();
})
.then((myJson) => {
if (myJson.totalHits > 0) {
setImages(myJson.hits);
showModal(images, handleClick);
}
});
};
const FormWrapper = styled.div`
text-align: left;
`;
const Container = styled.div``;
const LabelEl = styled.label``;
const Input = styled.input``;
const handleClick = (e) => {
const urlField = document.querySelector('#url');
urlField.value = e.target.src;
urlField.select();
document.execCommand("copy");
alert('URL has been copied to your clipboard. You may now paste it into the URL field.')
};
return (
<Container>
<FormWrapper>
<form onSubmit={handleSubmit}>
<LabelEl>
Enter Search Term
<Input type="text" name="query" value={query} onChange={e => setQuery(e.target.value)} />
</LabelEl>
<input type="submit" value="Submit" />
</form>
</FormWrapper>
</Container>
);
}
export default SearchImageForm;
const ImageResult = ({content, handleClick}) => (
<picture>
<img src={content.previewURL} alt="" onClick={handleClick}/>
</picture>
);
const [showModal, hideModal] = useModal(({images, handleClick}) => (<ReactModal isOpen ariaHideApp={false}>
<p>Found {images.length} image(s). Click an image to copy its URL to your clipboard.</p>
{images.map(image => <ImageResult key={image.id} content={image} handleClick={handleClick} />)}
<input type="text" name="url" id="url" key="url" />
<button onClick={hideModal}>Hide modal</button>
</ReactModal>));
When I try to run it, I get the React hooks error (Invalid Hook Call). Any ideas on what I am doing wrong here?
Here is the code on codesandbox, though i am not sure why it wont run.
https://codesandbox.io/s/blue-firefly-0sx6h
Thanks!
The useModal hook needs to be called inside your component.
From the Invalid Hook Call Warning documentation:
Hooks can only be called inside the body of a function component.
So the modification what you need to do is the following:
export function SearchImageForm(props) {
const [showModal, hideModal] = useModal(({images, handleClick}) => (
<ReactModal isOpen ariaHideApp={false}>
<p>Found {images.length} image(s). Click an image to copy its URL to your clipboard. </p>
{images.map(image => <ImageResult key={image.id} content={image} handleClick={handleClick} />)}
<input type="text" name="url" id="url" key="url" />
<button onClick={hideModal}>Hide modal</button>
</ReactModal>
));
// ... rest of your component code
return <>{/* your render */}</>
}
I hope that helps!

Categories

Resources