I've been reading a lot about the singleton pattern and how it's "bad" because it makes the classes using it hard to test so it should be avoided. I've read some articles explaining how the singleton could be replaced with dependency injection, but it seems unnecessarily complex to me.
Here's my problem in a bit more detail. I'm building a mobile app using React Native and I want to make a REST client that will communicate with the server, get data, post data and handle the login (store the login token and send it with each request after login).
My initial plan was to create a singleton object (RESTClient) that my app will use initially to login and then make request sending the credentials where needed. The DI approach seems really complicated to me (maybe because I never used DI before) but I'm using this project to learn as much as can so I want to do what's best here. Any suggestions and comments are much appreciated.
Edit: I've now realized I've worded my question poorly. I wanted some guidance on how to avoid the singleton pattern in RN and should I even do it. Luckily Samuel gave me just the kind of answer I wanted. My problem was I wanted to avoid the singleton pattern and use DI, but it seemed really complicated to implement it in React Native. I did some further research and implemented it using Reacts context system.
For anyone interested here's how I did it. Like I said, I used the context in RN which is something like props but it's propagated down to every component.
In the root component I provide the needed dependencies like this:
export default class Root extends Component {
getChildContext() {
restClient: new MyRestClient();
}
render() {...}
}
Root.childContextTypes = {restClient: PropTypes.object};
Now restClient is available in all components below Root. I can access it like this.
export default class Child extends Component {
useRestClient() {
this.context.restClient.getData(...);
}
render() {...}
}
Child.contextTypes = {restClient: PropTypes.object}
This effectively moves object creation away from logic and decouples the REST client implementation from my components.