ran*_*its 22 javascript reactjs react-native redux
我有一个React Native应用程序,我将使用WebSockets构建.我有一个用JavaScript编写的WebSocket库,我只是将它重新用于这个项目,这太棒了.
我的问题是,对React/React Native不熟悉,设置和维护通过WebSocket的所有流量的最佳做法是什么?
最初我的想法是在主App组件中创建websocket,如下所示:
export default class App extends Component {
constructor(props) {
super(props);
this.ws = new WebSocket;
}
componentWillMount() {
console.log(this.ws);
}
render() {
console.log("We are rendering the App component.....");
return (
<View style={styles.container}>
<Text style={styles.welcome}>Hello, world</Text>
</View>
);
}
}
Run Code Online (Sandbox Code Playgroud)
实际的WebSocket类将包含所有相应的连接处理:
ws.onopen = () => {
// connection opened
ws.send('something'); // send a message
};
ws.onmessage = (e) => {
// a message was received
console.log(e.data);
};
ws.onerror = (e) => {
// an error occurred
console.log(e.message);
};
ws.onclose = (e) => {
// connection closed
console.log(e.code, e.reason);
};
Run Code Online (Sandbox Code Playgroud)
我的问题是,由于通过WebSocket传入的数据将通过React Native应用程序中的许多组件适用于状态,但它不是可以扩展的类,React.Component我是否不在类中与Redux交互WebSocket?我是否将所有WebSocket连接处理移动到App组件并将操作发送到Redux?
这里常见的模式是实例化我的WebSocket类并确保其中的所有流量都正确地传递给Redux,以便所有组件的状态都能正确地漏斗?
Luk*_*uke 17
到目前为止这里的答案很棒 只是想补充一点,保存数据的地方应该根据它的数据类型做出决定.James Nelson有一篇关于这个主题的优秀文章,我经常提到这篇文章.
对于您的情况,让我们谈谈前三种类型的状态:
您的WebSocket连接是通用的,可以在技术上返回任何内容,但您收到的消息很可能是数据.例如,假设您正在构建聊天应用.然后,已发送和接收的所有消息的日志将是数据.您应该使用messagesreducer 将此数据存储在redux中:
export default function messages(state = [], action) {
switch (action.type) {
case 'SEND_MESSAGE':
case 'RECEIVE_MESSAGE': {
return [ ...state, action.message ];
}
default: return state;
}
}
Run Code Online (Sandbox Code Playgroud)
我们没有(并且我们不应该)在reducers中有任何WebSocket逻辑,因为它们是通用的,并不关心数据的来源.
另请注意,此减速器能够以完全相同的方式处理发送和接收.这是因为我们的通信状态reducer分别处理网络通信.
由于您使用的是WebSockets,因此您要跟踪的通信状态类型可能与我的示例不同.在使用标准API的应用中,我会跟踪请求何时加载,失败或成功.
在我们的聊天应用示例中,您可能希望在发送消息时跟踪这些请求状态,但也可能有其他事项要归类为通信状态.
我们的network减速机可以使用与减速机相同的动作messages:
export default function network(state = {}, action) {
switch (action.type) {
case 'SEND_MESSAGE': {
// I'm using Id as a placeholder here. You'll want some way
// to tie your requests with success/failure receipt.
return {
...state,
[action.id]: { loading: true }
};
} case 'SEND_MESSAGE_SUCCESS': {
return {
...state,
[action.id]: { loading: false, success: true }
};
} case 'SEND_MESSAGE_FAILURE': {
return {
...state,
[action.id]: { loading: false, success: false }
};
}
default: return state;
}
}
Run Code Online (Sandbox Code Playgroud)
通过这种方式,我们可以轻松找到请求的状态,而且我们不必为组件中的加载/成功/失败而烦恼.
但是,您可能不关心任何给定请求的成功/失败,因为您正在使用WebSockets.在这种情况下,您的通信状态可能只是您的套接字是否已连接.如果这对您来说听起来更好,那么只需编写一个connection响应打开/关闭操作的reducer.
我们还需要一些东西来发起消息.在聊天应用程序示例中,这可能是一个提交按钮,用于发送输入字段中的任何文本.我不会演示整个组件,因为我们将使用受控组件.
这里要说的是控制状态是发送之前的消息.在我们的案例中,有趣的代码是handleSubmit:
class ChatForm extends Component {
// ...
handleSubmit() {
this.props.sendMessage(this.state.message);
// also clear the form input
}
// ...
}
const mapDispatchToProps = (dispatch) => ({
// here, the `sendMessage` that we're dispatching comes
// from our chat actions. We'll get to that next.
sendMessage: (message) => dispatch(sendMessage(message))
});
export default connect(null, mapDispatchToProps)(ChatForm);
Run Code Online (Sandbox Code Playgroud)
所以,这解决了其中所有的国家去.我们创建了一个通用应用程序,可以使用操作来调用fetch标准API,从数据库或任意数量的其他来源获取数据.在您的情况下,您想要使用WebSockets.所以,这种逻辑应该存在于你的行动中.
在这里,您将创建所有的处理程序:onOpen,onMessage,onError等,这些仍然可以相当通用的,因为你已经得到了你的WebSocket工具单独设置.
function onMessage(e) {
return dispatch => {
// you may want to use an action creator function
// instead of creating the object inline here
dispatch({
type: 'RECEIVE_MESSAGE',
message: e.data
});
};
}
Run Code Online (Sandbox Code Playgroud)
我在这里使用thunk进行异步操作.对于这个特定的示例,这可能不是必需的,但您可能会遇到要发送消息然后处理成功/失败并从单个操作中向Reducer发送多个操作的情况sendMessage.Thunk非常适合这种情况.
最后,我们已经完成了所有设置.我们现在要做的就是初始化WebSocket并设置适当的监听器.我喜欢Vladimir建议的模式 - 在构造函数中设置套接字 - 但我会参数化你的回调,以便你可以交出你的行动.然后您的WebSocket类可以设置所有侦听器.
通过使WebSocket类成为单例,您可以从操作内部发送消息,而无需管理对活动套接字的引用.您还可以避免污染全局命名空间.
通过使用单例设置,无论何时new WebSocket()第一次呼叫,您的连接都将建立.因此,如果您需要在应用启动后立即打开连接,我会将其设置componentDidMount为App.如果延迟连接没问题,那么您可以等到组件尝试发送消息.该操作将创建一个新的WebSocket并建立连接.
Vla*_*pak 12
您可以创建专用的类,WebSocket并在任何地方使用它.它简单,简洁,清晰.此外,您将把所有与websockets相关的东西封装在一个地方!如果你希望你甚至可以在这个课程中创建单例,但总体思路是这样的:
class WS {
static init() {
this.ws = new WebSocket('ws://localhost:5432/wss1');
}
static onMessage(handler) {
this.ws.addEventListener('message', handler);
}
static sendMessage(message) {
// You can have some transformers here.
// Object to JSON or something else...
this.ws.send(message);
}
}
Run Code Online (Sandbox Code Playgroud)
你只在某处运行init index.js或app.js:
WS.init();
Run Code Online (Sandbox Code Playgroud)
现在,您可以从任何应用程序层,任何组件,从任何地方松散地发送消息:
WS.sendMessage('My message into WebSocket.');
Run Code Online (Sandbox Code Playgroud)
并从WebSocket接收数据:
WS.onMessage((data) => {
console.log('GOT', data);
// or something else or use redux
dispatch({type: 'MyType', payload: data});
});
Run Code Online (Sandbox Code Playgroud)
因此,即使在redux中,您也可以在任何操作或其他任何地方使用它!
| 归档时间: |
|
| 查看次数: |
3162 次 |
| 最近记录: |