score:13
This looks fine, but there are some things you can improve on, such as disconnecting the socket before unmounting and not making the socket part of state (refer to the code example below).
If you're confused over how to port existing code to hooks, write out the component using classes first, then port part by part to hooks. You could refer to this StackOverflow answer as a cheatsheet.
Using traditional classes, using socket.io looks like:
class App extends React.Component {
constructor(props) {
super(props);
this.socket = io();
}
componentDidMount() {
this.socket.open();
this.socket.emit('load settings');
this.socket.on('settings is here', (data) => {
// we get settings data and can do something with it
this.setState({
settings: data,
})
});
}
componentWillUnmount() {
this.socket.close();
}
render() {
...
}
}
Then you can port the this.socket
to use useRef
(it doesn't need to be part of state
as your render()
function doesn't need it. So useRef
is a better alternative (although useState
is likely to still work).
Port componentDidMount()
via using useEffect
and passing an empty array as the second argument to make the effect callback only run on mount.
Port componentWillUnmount()
via returning a callback function in the useEffect
callback which React will call before unmounting.
function App() {
const socketRef = useRef(null);
const [settings, setSettings] = useState(false);
useEffect(() => {
if (socketRef.current == null) {
socketRef.current = io();
}
const {current: socket} = socketRef;
try {
socket.open();
socket.emit('load settings');
socket.on('settings is here', (data) => {
// we get settings data and can do something with it
setSettings(data);
})
} catch (error) {
console.log(error);
}
// Return a callback to be run before unmount-ing.
return () => {
socket.close();
};
}, []); // Pass in an empty array to only run on mount.
return ...;
}
score:7
The accepted answer has the downside, that the initial state of the useRef() gets called on every re-render. With a text input for example, a new connection is established on every input change. I came up with two solutions:
- Define the socket in the useEffect
const ChatInput = () => {
const [chatMessage, setChatMessage] = useState<string>('');
const socket = useRef<Socket>();
useEffect(() => {
socket.current = io('my api');
socket.current.on('chat message', (message: string) => {
setChatMessage(message);
});
return () => { socket.current?.disconnect(); };
}, []);
const inputHandler = (text: string) => {
socket.current?.emit('chat message', text);
};
return (
<View>
<Text>{chatMessage}</Text>
<TextInput onChangeText={(text) => inputHandler(text)} />
</View>
);
};
- Define the socket.io in a useState()
const ChatInput = () => {
const [chatMessage, setChatMessage] = useState<string>('');
const [socket] = useState(() => io('my api'));
useEffect(() => {
socket.on('chat message', (message: string) => {
setChatMessage(message);
});
return () => { socket.disconnect(); };
}, []);
const inputHandler = (text: string) => {
socket.emit('chat message', text);
};
return (
<View>
<Text>{chatMessage}</Text>
<TextInput onChangeText={(text) => inputHandler(text)}/>
</View>
);
};
export default ChatInput;
Source: stackoverflow.com
Related Query
- Right way to fetch data with react using socket.io
- React Hook useEffect : fetch data using axios with async await .api calling continuous the same api
- How to fetch data from a custom React hook (API) with onClick and display it in a Div using TypeScript?
- Best way to fetch data from a REST api using react hooks and context for state management?
- Is it an incorrect practice to use URL params as a way to fetch data using react router in an react application?
- Is there a way to cache data coming from redux connect in React function component with using useRef()?
- React - the right way to show data using multiple react-bootstrap modal
- Right way to update state with react socket hooks
- What is the best way to deal with a fetch error in react redux?
- What's the right way to float right or left using the material-ui appbar with material-ui-next?
- How to fetch the new data in response to React Router change with Redux?
- Is there a right way to pass data into a React component from the HTML page?
- Is there any way to see names of 'fields' in React multiple state with React DevTools when using 'useState' hooks
- Proper way of using WebSockets with React Native
- react native post form data with object and file in it using axios
- Multiple fetch data axios with React Hooks
- Best way to submit FORM data with React Redux?
- Search not working with React material-table using remote data
- Post an object with fetch using react js and express API server
- Using fetch to render json data in react app
- With a React Hook, trying to fetch multiple datas using forEach
- Fetch data with React
- What is ACTUALLY the right way to transition/redirect using React Router?
- Unit test form submission with data using react testing library
- How to refer to data with permalinks using react router
- displaying data from fetch api using react
- Fetch data with a custom React hook
- Two way data binding in React with Hooks
- What is the best way to save my dynamicly created data using React and Javascript?
- Is there any way to crop videos in JavaScript with a crop box, without using React or Vue?
More Query from same tag
- Can't pass a head of a method to event handling in React markup
- Create-React-App Proxy in Production Build
- How to cover lines in mapDispatchToProps with Jest?
- React.js - Value of checkbox not reflecting initial state
- Rendering a Google Map without react-google-map
- Date string to date object
- How do i get multiple parameters working with React Router
- Jest unit test - How do I call through async function in a setTimeout repeating function
- Testing React Component className with enzyme
- How to get Children width in Reactjs
- docker compose erroring out about python files when starting React apps
- How to generate a menu based on the files in the pages directory in Next.js
- useEffect throws an error when used to set input value
- Unable to update form field in react via prevState
- React: Why doesn't the state of my app become updated?
- how to set min height in semantic-ui react
- ReactJS how to structure components similar to django?
- How to give border radius react-bootstrap dropdowns
- Rendering react navigation screens inside a scrollview
- How to make aspecific API call from within a Line Chart class in ReactJS using react-chartjs-2?
- simple Debounce not working in react 16 but works in jsfiddle with react 14.3
- Set new Sequence in Object from Array after deletion of specific object
- SCRIPT1028: SCRIPT1028: Expected identifier, string or number
- Fetch returns string instead of JSON
- onCompleted handler not firing with Apollo Client Query
- React Native Vscode TypeScript debugger stepping extremely slow
- Automatically adjust width of chip component (div) based on text of child elements
- How to Redirect back to my website after transaction ends on Razorpay . Note: if "redirect=true" is passed as an option
- Defining common methods for React functional component
- Adding properties to an existing type in a different files with TypeScript