#javascript #reactjs #mapping
#javascript #reactjs #отображение
Вопрос:
index.js
const UserSearch = ({ user }) => {
const [resultsToShow, setResultsToShow] = useState([])
const maxDistance = useFilter('matchaMaxDistance', 100, 'number')
const minAge = useFilter('matchaMinAge', 20, 'number')
const maxAge = useFilter('matchaMaxAge', 120, 'number')
const minFame = useFilter('matchaMinFame', 100, 'number')
const requiredTag = useFilter('matchaRequiredTag', '', 'text')
const sortFormProps = ({ user, resultsToShow, setResultsToShow })
const filterFormProps = ({ user, requiredTag, maxDistance, minFame, minAge, maxAge })
const requiredTagFound = tags => tags amp;amp; requiredTag.value
? tags.split('#').includes(requiredTag.value)
: true
const filterResults = () => resultsToShow
? resultsToShow
.filter(r => r.distance <= maxDistance.value amp;amp;
r.age.years >= minAge.value amp;amp; r.age.years <= maxAge.value
amp;amp; r.fame >= minFame.value amp;amp; requiredTagFound(r.tags))
: []
var unblockedUser = [];
useEffect(() => {
var coords = JSON.parse(window.localStorage.getItem('loggedMatchaUser'));
var from_user_id = coords.user_id;
var res = filterResults();
console.log(typeof res)
res.map((r) => {
var to_user_id = r.user_id;
blockService.blockedUser({from_user_id, to_user_id})
.then(res => {
//If this row exist in the table it return 1 otherwise 0
if (res.value === 0)
{
//console.log(r);
unblockedUser.push(r)
}
})
.catch(e => {
console.log(("Error: couldn't get block info"))
})
})
}, [filterFormProps])
//console.log(unblockedUser)
return <>
<ListOfUsers users={unblockedUser} />
</>
}
export default UserSearch
ListOfUsers.js
const ListOfUsers = ({ users }) => {
console.log(users);
return (
users amp;amp; users.length > 0
? <ListGroup className="text-left" variant="flush">
{users.map(u => <Link to={`/users/${u.user_id}`} key={u.user_id}>
<ListGroup.Item>
<div style={{display: "inline-block", width: "60%"}}>{u.username}, {u.age.years}</div>
<div style={{display: "inline-block", width: "40%", textAlign: "right"}}>{parseInt(u.distance)} km<br />
<FontAwesomeIcon icon={faAward} /> {u.fame}</div>
</ListGroup.Item>
</Link>)}
</ListGroup>
: <div className="text-info">Could not find any matching users<br />please try different filters</div>
)
}
Я работаю с поиском пользователей. Моя конечная цель — отобразить список пользователей, кроме заблокированных пользователей, в качестве результата поиска зарегистрированного пользователя. Что я пытаюсь здесь сделать, так это то, что я отправляю unblockedUser в качестве реквизита компоненту ListOfUsers. В компоненте ListOfUsers, если я консольный пользовательский реквизит, он выглядит следующим образом
Мой вопрос в том, почему моя функция map не работает здесь, в компоненте ListOfUsers. Как я могу заставить его работать? Кроме того, если я утешаю длину пользователей, она возвращает undefined.
Заранее спасибо
Ответ №1:
Я думаю, нужно создать геттер, сеттер, используя unblockedUser в качестве useState
.
const [unblockedUser, setUnblockedUser] = useState([]); // try it this
useEffect(() => {
const coords = JSON.parse(window.localStorage.getItem('loggedMatchaUser'));
const from_user_id = coords.user_id;
const res = filterResults(); //how does work filterResults() funtinon?
console.log(typeof res)
res.map((r) => {
const to_user_id = r.user_id;
blockService.blockedUser({from_user_id, to_user_id})
.then(res => {
//If this row exist in the table it return 1 otherwise 0
if (res.value === 0)
{
//console.log(r);
setUnblockedUser((prevState) => [...prevState, r]) //here
}
})
.catch(e => {
console.log(("Error: couldn't get block info"))
})
})
}, [filterFormProps]) // => [] to change
//console.log(unblockedUser)
return <>
<ListOfUsers users={unblockedUser} />
</>
Возможно, вы не полностью функциональны, потому что функция другой функции не объяснена, но попробуйте.
Комментарии:
1. Здравствуйте, спасибо за ваш комментарий. А вот функция filterResults(): « const filterResults = () => resultsToShow ? resultsToShow .filter(r => r.distance <= maxDistance.value amp;amp; r.age.years >= minAge.value amp;amp; r.age.years <= maxAge.value amp;amp; r.fame >= minFame.value amp;amp; requiredTagFound(r.tags)) : [] «
2. Я обновил свой вопрос другими кодами. Пожалуйста, проверьте. Ваш приведенный выше ответ не будет работать. Ваш код отображает компонент бесконечное количество раз (он не останавливается). Это означает, что он постоянно попадает в базу данных и извлекает данные из таблицы. Это не останавливается. Мне пришлось остановить серверный сервер, который является узлом js
3. @Mahmudul Hasan Пожалуйста, скажите мне
resultsToShow
, какое значение вы хотите обновить. и ‘filterResults’ Обновление событияresultsToShow
setResultsToShow
отсутствует в вашем коде. Причина, по которой рендеринги продолжают происходить, заключается в том, что нам нужно удалить[filterFormProps]
useEffect
их и посмотреть, работает ли это.[filterFormProps]
=>[ ]
Ответ №2:
Проблема в том, что вы определяете unblockedUser
вне своего useEffect
хука, а затем unblockedUser
асинхронно обновляете его внутри useEffect
. So unblockedUser
не получает его содержимое до завершения рендеринга (когда уже слишком поздно), а при следующем рендеринге unblockedUser
переопределяется как пустой список.
Чтобы исправить это, я бы сохранил unblockedUser
его как переменную состояния, затем вы можете обновить его, как вам нравится, и изменения будут отображаться соответствующим образом.
Например (с минимальными изменениями в существующем коде):
const [unblockedUser, setUnblockedUser] = React.useState([]); // changed
useEffect(() => {
var coords = JSON.parse(window.localStorage.getItem('loggedMatchaUser'));
var from_user_id = coords.user_id;
var res = filterResults();
console.log(typeof res)
setUnblockedUser([]); // clear before rerunning
res.map((r) => {
var to_user_id = r.user_id;
blockService.blockedUser({from_user_id, to_user_id})
.then(res => {
//If this row exist in the table it return 1 otherwise 0
if (res.value === 0)
{
//console.log(r);
setUnblockedUser(prev => [...prev, r]); // changed
}
})
.catch(e => {
console.log(("Error: couldn't get block info"))
})
})
}, [filterFormProps])
//console.log(unblockedUser)
return <ListOfUsers users={unblockedUser} />
В приведенном выше примере я внес как можно меньше изменений в ваш код, чтобы упростить отслеживание изменений. Вы можете обнаружить, что дополнительные модификации улучшат этот код. Например, вы можете сначала проверить все записи пользователей, получить один массив разблокированных пользователей, а затем вызвать setUnblockedUser
один раз вместо нескольких раз. Но решать вам.
Комментарии:
1. Привет @Henry, спасибо за комментарий. Ваш код выдает это предупреждение Предупреждение: обнаружено два дочерних элемента с одним и тем же ключом,
10
. Ключи должны быть уникальными, чтобы компоненты сохраняли свою идентичность при обновлениях. Неуникальные ключи могут Этот код отображает компонент бесконечное время (он не останавливается). Это означает, что он постоянно попадает в базу данных и извлекает данные из таблицы. Это не останавливается. Мне пришлось остановить внутренний сервер, который является node js. Знаете, почему это происходит?2. Я обновил свой вопрос другими частями своего кода. Пожалуйста, проверьте 🙂
3. @MahmudulHasan Ах да, не хватало вызова для очистки
unblockedUser
перед повторным заполнением. Сделано обновление