#javascript #reactjs
Вопрос:
import { useState, useEffect } from 'react';
import socketConnection from '../../connection';
import NavBar from '../../../Component/NavBar.';
const ws = socketConnection();
export default function GetEvent() {
const [matchTime, setMatchTime] = useState('');
const [teamNames, setTeamNames] = useState('');
const [market, setMarket] = useState('');
const [isLoading, setLoading] = useState(true);
const [socketData, setSocketData] = useState([]); // array of objects.
useEffect(() => {
ws.onopen = () => ws.send(
/* eslint-disable */
JSON.stringify({
keys: ['xyz'],
type: 'getEvent',
id: 111,
keys: ['skd'],
type: 'getMarket',
id: 222,
}),
);
function handleMessage(event) {
console.log('Handling message');
setLoading(true);
const parsedData = JSON.parse(event.data);
console.log(parsedData);
setMatchTime(parsedData.data.startTime);
setTeamNames(parsedData.data.name);
setSocketData((currentSocketData) => [...currentSocketData, parsedData]);
setMarket((currentSocketData) => [...currentSocketData, parsedData[1]]);
setLoading(false);
}
ws.addEventListener('message', handleMessage);
return () => ws.removeEventListener('message', handleMessage);
}, []);
@консоль разработчиков
console.log(matchTime);
массив неопределенных объектов. —ожидается ‘2020 09 02’
console.log(teamNames);
в полдень/полный рабочий день-ожидается ‘рейнджеры против волков’
console.log(market);
массив неопределенных объектов. —ожидается ‘Перерыв/полный рабочий день’
Я также пробовал визуализировать как разные компоненты, но это не имеет смысла, так как это просто строки из API.
return (
<>
<NavBar />
<div className="footyevent" data-testid="footy-event-id">
<div className="container">
<h1>Football</h1>
<div className="title-box">
{isLoading amp;amp; <div className="loading">Not Connected... Please
Refresh</div>}
</div>
<div className="title-box">
<div className="startTime" data-testid="event-time-id">
Date amp; Time: {matchTime} {/* blanc */}
</div>
</div>
<div className="title-box">
<div className="teams" data-testid="playing-teams-id">
{teamNames} {/* HalfTime/FullTime */}
</div>
</div>
<div className="title-box">
<div className="socket-data" data-testid="socket-data-id">
{socketData.map((x, index) => (
<p>
{x.data.name} {/* HalfTime/FullTime */}
</p>
))}
</div>
</div>
</div>
</div>
</>
);
}
Behaviour is fine with a single API call of
JSON.stringify({
keys: ['xyz'],
type: 'getEvent',
id: 212,
}),
);
update: I’m finding it difficult now to resolve or map over the data(objects) received from the WebSocket server response.
export default function GetEvent() {
const [isLoading, setLoading] = useState(true);
const [socketData, setSocketData] = useState([]); // objects.
useEffect(() => {
ws.onopen = () => {
ws.send(
/* eslint-disable */
JSON.stringify({
keys: ['xyz'],
type: 'getEvent',
id: 111,
}),
);
ws.send(
/* eslint-disable */
JSON.stringify({
keys: ['skd'],
type: 'getMarket',
id: 222
}),
);
};
function handleMessage(event) {
console.log('Handling message');
setLoading(true);
const parsedData = JSON.parse(event.data);
console.log(parsedData);
setSocketData((currentSocketData) => [...currentSocketData, parsedData]);
setLoading(false);
}
ws.addEventListener('message', handleMessage);
return () => ws.removeEventListener('message', handleMessage);
}, []);
socketData.forEach(x => x.forEach(y => {
if (x.type === 'EVENT_DATA') {
console.log(`event data: ${y.data.name}`);
} else if (x.type === 'BET_DATA') {
console.log(y.data.name);
}
}));
return (
<>
<div className="title-box">
<div key="uniqueId2" className="teams" data-testid="playing-teams-id">
{socketData.map(data1 => console.log(data1))}
</div>
</div>
</>
);
}
Данные и ошибки консоли
перебор данных сокета, зарегистрированных:
Uncaught TypeError: x.forEach is not a function
console.log(данные 1):
{type: 'EVENT_DATA', data: {…}}
data: {
id: 1;
name: 'A';
date: '12020507'
}
{type: 'MARKET_DATA', data: {…}}
data: {
id: 1;
name: 'Final Result';
}
console.log(данные 1[0])
undefined
консоль.журнал(data1.name):
'A'
'Final Result'
Комментарии:
1. Какой ответ вы получаете, когда отправляете массив объектов и массив объектов в JSON.stringify?
2. Это может быть связано с тем фактом, что у вас есть дубликаты ключей в json, которые вы отправляете. Затем, когда вы пытаетесь проанализировать его, вы получаете неопределенные значения. Попробуйте отправить json с уникальными ключами.
3. да, это @Giovanni. Мне просто нужно разрешить/сопоставить ответ полученного объекта сейчас.
Ответ №1:
Ваша главная проблема, вероятно, в том,:
JSON.stringify({
keys: ['xyz'],
type: 'getEvent',
id: 111,
keys: ['skd'],
type: 'getMarket',
id: 222,
})
Если вы используете дубликаты ключей в объектных литералах, они переопределят предыдущее значение.
({ a: 1, b: 2, c: 3, a: 4, b: 5 }) //=> { a: 4, b: 5, c: 3 }
Это означает, что значение первых 3 ключей (ключи, тип и идентификатор) будет потеряно.
Я не знаю, чего ожидает ваша розетка. Если он принимает массивы, вам следует вместо этого использовать следующее.
ws.send(JSON.stringify([{
keys: ['xyz'],
type: 'getEvent',
id: 111,
}, {
keys: ['skd'],
type: 'getMarket',
id: 222,
}]))
В качестве альтернативы вы можете отправить 2 отдельных запроса.
ws.send(JSON.stringify({
keys: ['xyz'],
type: 'getEvent',
id: 111,
}))
ws.send(JSON.stringify({
keys: ['skd'],
type: 'getMarket',
id: 222,
}))
Для этого последнего вам, возможно, придется настроить handleMessage
функцию. Потому что вместо того, чтобы оба результата были в одном ответе, обработчик будет вызван 2 раза.
Комментарии:
1. спасибо, @3limin4t0r Я подумал, что могу отправить 2 отдельных запроса, но моя проблема заключается в том, чтобы разрешить полученные данные WebSocket, поскольку они пришли в виде объектов, и я не смог сопоставить их. Я попробовал
socketData.forEach(x => x.forEach(y => { if (x.type === 'EVENT_DATA') { console.log(
данные о событиях: ${y.data.name}); } else if (x.type === 'BET_DATA') { console.log(y.data.name); } }));
Но я получилUncaught TypeError: x.forEach is not a function
2. @saint Не могли бы вы поделиться структурой, которую вы получаете обратно? Текущая ошибка говорит вам , что
socketData
у вас нет функцииforEach
, что означает, что это не массив.3. да, @3limin4t0r. в цепочке нет необходимости, так как x-это объект, а не массив. Так что итерации на socketData просто достаточно.
Ответ №2:
Это мой ответ, любезный рефакторинг
export default function GetEvent() {
const [socketData, setSocketData] = useState([]);
useEffect(() => {
ws.onopen = () => {
ws.send(
);
ws.send(
);
};
function handleMessage(event) {
}
ws.addEventListener('message', handleMessage);
return () => ws.removeEventListener('message', handleMessage);
}, []);
const myDom1 = socketData.map((dataObject, index, arr) => {
if (dataObject.type === 'event-data') {
return dataObject.data.startTime
}
})
const myDom2 = socketData.map((dataObject, index, arr) => {
if (dataObject.type === 'market') {
return dataObject.data.name
}
})
const myDom3 = socketData.map((dataObject, index, arr) => {
same...
}
})
return (
<>
<div className="t-b">
<div key="uniqueId1" className="teams" data-testid="">
<p>{myDom1}</p>
</div>
</div>
<div className="t-b">
<div key="uniqueId2" className="teams" data-testid="">
<p>{myDom2}</p>
</div>
</div>
<div className="t-b">
<div key="uniqueId3" className="" data-testid="">
<p>{myDom3}</p>
</div>
</div>
</>
);
}
Комментарии:
1. Пожалуйста, добавьте дополнительные сведения, чтобы расширить свой ответ, например, ссылки на рабочий код или документацию.