#javascript #html #reactjs #axios
#javascript #HTML #reactjs #axios
Вопрос:
У меня есть панель поиска с двумя объединяемыми полями ввода. Первый ввод — это «desc», а второй — «местоположение». Каждый раз, когда я пытаюсь его использовать, они всегда принимают входное значение «desc», хотя я также заполняю поле ввода «местоположение». Когда я пытаюсь использовать второе поле ввода, всегда появляется входное значение «местоположение» undefined
.
Вы можете найти мой код ниже:
import React, { useEffect, useState } from 'react';
import axios from 'axios';
import { Link } from 'react-router-dom';
const Home = () => {
const [jobs, setJobs] = useState([]);
const [find, setFind] = useState("");
useEffect(() => {
getJobsAPI();
// eslint-disable-next-line react-hooks/exhaustive-deps
},[])
const getJobsAPI = () => {
axios.get(`https://api.allorigins.win/raw?url=https://jobs.github.com/positions.json`)
.then((res) => {
setJobs(res.data)
})
}
const findJobsAPI = async (desc, location) => {
await axios.get(`https://api.allorigins.win/raw?url=https://jobs.github.com/positions.json?description=${desc}amp;location=${location}`)
.then((res) => {
setJobs(res.data)
})
}
const handleChange = (e) => {
setFind(e.target.value)
}
const handleSubmit = (e) => {
e.preventDefault();
findJobsAPI(find);
setFind("");
e.target.reset();
}
return (
<>
<div className="mx-6 my-4">
<form onSubmit={handleSubmit}>
<div className="grid grid-cols-4">
<div>
<p>Job Description</p>
<input
className="py-0.5 px-2 mr-3 border-gray-300 border-2"
placeholder="Filter by title, benefits, companies, expertise"
name="desc"
onChange={(e) => handleChange(e)}
/>
</div>
<div>
<p>Location</p>
<input
className="py-0.5 px-2 mr-3 border-gray-300 border-2"
placeholder="Filter by city, state, zip code or country"
name="location"
onChange={(e) => handleChange(e)}
/>
</div>
<div>
<input type="checkbox" />
<label className="font-semibold ml-2">Full Time Only</label>
</div>
<div>
<button type="submit" className="text-white font-semibold rounded bg-gray-500 py-2 px-3 hover:bg-gray-800 hover:transition duration-300 ease-in-out">Search</button>
</div>
</div>
</form>
<div>
<p className="text-black font-semibold text-3xl">Job List</p>
</div>
{jobs.map((item) => (
<div key={item.id} className="border-t-2">
<div className="my-3">
<div className="flex flex-wrap justify-between">
<Link to={`/positions/${item.id}`}>
<p className="text-primary-blue font-bold text-xl hover:text-blue-700 hover:transition duration-300 ease-in-out">{item.title}</p>
</Link>
<p>{item.location}</p>
</div>
<div className="flex flex-wrap justify-between">
<p className="text-gray-500">{item.company} - <b className="text-primary-green">{item.type}</b></p>
<p>{item.created_at}</p>
</div>
</div>
</div>
))}
</div>
</>
)
}
export default Home;
Комментарии:
1. Вы вызываете
findJobsAPI(find);
только с одним параметром
Ответ №1:
Хотя у вас есть два поля, вы используете только один обработчик событий для них, и оба этих поля обновляют одно и то же состояние. Вместо того, чтобы использовать одно состояние ( find
) для двух полей, вы можете использовать два состояния ( location
и description
) и обновлять их при изменении ввода. findJobsAPI
Вам не нужно указывать какие-либо аргументы, поскольку функция имеет доступ к этим значениям.
function App() {
const [jobs, setJobs] = React.useState([]);
const [description, setDescription] = React.useState('');
const [location, setLocation] = React.useState('');
const [loading, setLoading] = React.useState(false);
// ...
const findJobsAPI = () => {
setLoading(true);
const URL = encodeURIComponent(
`https://jobs.github.com/positions.json?description=${description}amp;location=${location}`
);
fetch(`https://api.allorigins.win/raw?url=${URL}`)
.then((res) => res.json())
.then((data) => {
setJobs(data);
setLoading(false);
});
// you should handle errors!
};
const handleSubmit = (e) => {
e.preventDefault();
findJobsAPI();
setDescription('');
setLocation('');
};
return (
<form onSubmit={handleSubmit}>
<div>
<label>
Job Description
<input
placeholder="Filter by title, benefits, companies, expertise"
name="desc"
onChange={(e) => setDescription(e.target.value)}
value={description}
/>
</label>
</div>
<div>
<label>
Location
<input
placeholder="Filter by city, state, zip code or country"
name="location"
onChange={(e) => setLocation(e.target.value)}
value={location}
/>
</label>
</div>
<button type="submit">Search</button>
<pre>{JSON.stringify({ loading, description, location }, null, 2)}</pre>
<pre>{JSON.stringify({ jobs }, null, 2)}</pre>
{/* ... */}
</form>
// ...
);
}
ReactDOM.render(<App />, document.getElementById('root'));
body {
font-family: sans-serif;
}
button,
input {
font-family: inherit;
font-size: inherit;
padding: 0.325rem 0.5rem;
}
input {
display: block;
margin-bottom: 0.5rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Комментарии:
1. я просто пробую ваш код, он работает, но проблема в том, что когда я пытаюсь выполнить поиск в поле ввода «местоположение», данные не обновляются, есть ли у вас какие-нибудь советы по этому поводу?
2. Похоже, для меня это также обновляет местоположение. Что вы подразумеваете под тем, что данные не будут обновляться ? Данные, полученные из GitHub, или значение поля?
3. О, я вижу, вы имели в виду извлеченные данные. Это потому, что URL, на который вы переходите
allorigins.win
, должен быть закодирован, если он содержит строку запроса. Проверьте приведенный выше фрагмент, теперь он должен работать так, как ожидалось. Я использую выборку вместо axios выше, поскольку я не хотел ничего импортировать сюда.4. о, хорошо, я понял, большое спасибо за вашу помощь: D