地图数据值从WebSocket到表格行

时间:2019-01-21 07:17:18

标签: reactjs redux

我正在使用saga在React Redux中学习Websocket的使用方法。在这段时间里,我在传奇中传递了api,并试图在我的页面中获得价值。 这里的问题是该值来自saga,并且还在屏幕上打印,但是我无法映射该值并从该api数据中打印特定数据

这是我在其中呼叫数据的页面。

import React, { Component } from 'react'
import { connect } from 'react-redux';
import { open, close, message } from '../action/action';
import { STATE_ONCLOSE, STATE_ONOPEN, STATE_ONERROR, STATE_ONMESSAGE } from '../reducer/reducer'
import { Button, Table } from 'reactstrap'

const wsid = 'wsid';

class WebSoketEcho extends Component {
    constructor(props) {
        super(props);
        this.state = {
            messagearea: '',
            addressarea: '',
            value: [],

        };
    }
    sendHandle() {
        this.props.dispatch(message(wsid, this.state.messagearea));
        this.setState({ messagearea: '' });
    }
    closeHandle() {
        this.props.dispatch(close(wsid, false, { code: 1000, reason: 'text' }));
    }
    openHandle() {
        this.props.dispatch(close(wsid));
        this.props.dispatch(open(wsid, this.state.addressarea));

    }
    componentWillUnmount() {
        this.closeHandle();
    }

    render() {
        let ws = this.props.websocket;
        let ls = [];
        ls = this.props.websocket;
        console.log("ls data", ls)
        console.log("Render Data", ws);
        const { state = '', event = null } = ws[wsid] ? ws[wsid] : {};
        let viewValue = [];
        console.log("Get DATAAAA", state);
        switch (state) {
            case STATE_ONOPEN:
            case STATE_ONERROR:
                break;
            case STATE_ONMESSAGE:
                viewValue = event.data;
                    // this.setState({[this.state.value]:event.data})
                break;
            case STATE_ONCLOSE:
                viewValue = event.code + ":" + event.reason;
            //   this.setState({[this.state.value]:event.code+":"+event.reson});
            // this.state.value=event.code+":"+event.reson    
            break;
        }
        return (
            <div>
                <p>state:{state}</p>
                <p>value:{viewValue
                    }</p>
                <Table>
                    <thead>
                        <tr>
                            <td>Pair</td>
                            <td>Amount</td>
                            <td>Price</td>
                        </tr>
                    </thead>
                    <tbody>
                        {console.log("State", this.props.websocket)}

                        {/* {this.data.map((detais,index)=>{
                            <tr>
                                <td key={index}>{detais.p}</td>
                            </tr>
                        })}         */}
                   
                        <tr>
                            <td >{viewValue}</td>
                            <td >{viewValue}</td>
                            <td >{viewValue}</td>

                        </tr>

                    </tbody>
                </Table>
                <button type="button" onClick={() => this.openHandle()}>Open</button>
                <button type="button" onClick={() => this.closeHandle()}>Close</button><br />
                {/* <input type="text" value={this.state.addressarea} onChange={(e)=>this.setState({addressarea:e.target.value})} placeholder="input address" /><br/>
        <textarea name="messagearea" value={this.state.messagearea} onChange={(e) => this.setState({messagearea: e.target.value})} placeholder="input your text"></textarea>
        <button type="button" onClick={()=>this.sendHandle()}>Send</button> */}
            </div>
        )
    }
}
function mapStateToProps(websocket) {


    console.log("Map Data:", websocket);
    return websocket ;

}
function mapDispatchToProps(dispatch) {
    return {
        dispatch
    };
}
export default connect(mapStateToProps, mapDispatchToProps)(WebSoketEcho);

我的动作文件在这里

import { createAction } from 'redux-act';
const WSHEADER = '@@redux-saga-websocket-';

export const OPEN = WSHEADER + 'open';
export const MESSAGE = WSHEADER + 'message';
export const CLOSE = WSHEADER + 'close';
export const REMOVE = WSHEADER + 'remove';
export const ONOPEN = WSHEADER + 'onopen';
export const ONMESSAGE = WSHEADER + 'onmessage';
export const ONCLOSE = WSHEADER + 'onclose';
export const ONERROR = WSHEADER + 'onerror';

export const open = createAction(OPEN, (id, url, option) => ({ id, url, option }));
export const message = createAction(MESSAGE, (id, data, option) => ({ id, data, option }));
export const close = createAction(CLOSE, (id, removal, option) => ({ id, removal, option }));
export const remove = createAction(REMOVE, (id) => ({ id }));
export const onopen = createAction(ONOPEN, (id, event) => ({ id, event }));
export const onmessage = createAction(ONMESSAGE, (id, event) => ({ id, event }));
export const onclose = createAction(ONCLOSE, (id, event) => ({ id, event }));
export const onerror = createAction(ONERROR, (id, event) => ({ id, event }));

Reducer看起来像这样

import { createReducer } from 'redux-act';
import { onopen, onclose, onmessage, onerror, remove } from '../action/action';

export const STATE_UNINITIALIZED = 'uninitialized';
export const STATE_ONOPEN = 'onopen';
export const STATE_ONCLOSE = 'onclose';
export const STATE_ONMESSAGE = 'onmessage';
export const STATE_ONERROR = 'onerror';


export const initialState = {
    websocket: {}
};


function updateStateCreator(eventType) {
    return (state, payload ) => {
        const update = {};
        update.websocket = {};
        update.websocket[payload.id] = {
            state: eventType,
            event: payload.event
        };
        return Object.assign({}, state, update);
    }
}
export default createReducer({
    [onopen]: updateStateCreator(STATE_ONOPEN),
    [onclose]: updateStateCreator(STATE_ONCLOSE),
    [onmessage]: updateStateCreator(STATE_ONMESSAGE),
    [onerror]: updateStateCreator(STATE_ONERROR),
    [remove]: (state, payload) => {
        const update = Object.assign({}, state);
        delete update.websocket[payload.id];
        return update;
    }
}, initialState);

Saga文件在这里

import { eventChannel,END} from 'redux-saga';
import { fork, take, call, put, cancel,takeEvery} from "redux-saga/effects";
import {onopen,onmessage,onclose,onerror,open,message,close} from "../action/action";
/**
 * https://github.com/kuy/redux-saga-chat-example/blob/master/src/client/sagas.js
 */

const sockets={};
function getSocket(id){
	return sockets[id];
}
function setSocket(id,socket){
	sockets[id]=socket;
}
function deleteSocket(id){
	delete sockets[id];
}
/**
 * [connect description]
 * @param  {string} url    url
 * @param  {Object} option protocol,binaryType
 * @return {WebSocket} socket 
 */
function connect(id,option={}){
	if(!getSocket(id)){
			const socket=new WebSocket("wss://stream.binance.com:9443/ws/btcusdt@aggTrade",option.protocol);
			socket.binaryType=option.binaryType?option.binaryType:socket.binaryType;
			setSocket(id,socket);
			return socket;
	}
	return null;
}
function* read(socket,id){
	const channel = yield call(subscribe, socket,id);
	while(true){
		const action=yield take(channel);
		yield put(action);
	}
	//yield takeEvery(channel,put); 
	//This is not supported by redux-saga-test-plan 3.5.0. If redux-saga-test-plan will support this in the future, It can use this.
}

/**
 * 
 * @param  {WebSocket} socket [description]
 * @return {[type]}        [description]
 */
function subscribe(socket,id){
	return eventChannel(emitter=>{
		socket.addEventListener('open',event=>{
			emitter(onopen(id,event));
		});
		socket.addEventListener('error',event=>{
			emitter(onerror(id,event));
		});
		socket.addEventListener('close',event=>{
			emitter(onclose(id,event));
			emitter(END);
			deleteSocket(id);
		});
		socket.addEventListener('message',event=>{
			emitter(onmessage(id,event));
		});
		return ()=>{};
	});
}

function* messageWatcher(){
		yield takeEvery(`${message}`,messageWorker);
}

function* messageWorker(action){
	const {id,data,option={}}=action.payload;
	const socket=yield call(getSocket,id);
	if(socket){
			socket.binaryType=option.binaryType?option.binaryType:socket.binaryType;
			yield call(socket.send.bind(socket),data);
	}
}
function* closeWatcher(){
	yield takeEvery(`${close}`,closeWorker);
}
function* closeWorker(action){
	const {id,removal,option={}}=action.payload;
	const socket=yield call(getSocket,id);
	if(socket){
		yield call(socket.close.bind(socket),option.code,option.reason);
		yield call(deleteSocket,id);
		// if(removal){
		// 	yield put(remove,id);
		// }
	}
}
function* openWatcher(){
	yield takeEvery(`${open}`,openWorker);
}
function* openWorker(action){
	const {id,url,option={}}=action.payload;
	const socket=yield call(connect,id,url,option);
	if(socket){
		yield fork(read,socket,id);
	}
}
export default function* wsStart(){
	yield fork(openWatcher);
	yield fork(closeWatcher);
	yield fork(messageWatcher);
}

在这里,我也分享了我作为示例的链接。 enter link description here

1 个答案:

答案 0 :(得分:0)

您需要使用Object.keys来迭代对象,例如

 Object.keys(data).map(item=>{
            return(
                <li>{ "Key :"+item +" Value:  " +data[item]}</li>
            )
        })

工作演示Demo