Das beste React State Management auswählen

Dieser Artikel erschien ursprünglich im Entwickler.de-Magazin

Wenn man sich in der Community umschaut, dann trifft man immer wieder auf folgende Fragestellung: Wie manage ich meinen State in React?[1]n00b Q: Why would you ever use React w/o Hooks?

Speziell Devs, die vorher mit anderen Frameworks wie Angular oder Vue gearbeitet haben, fragen sich, wie sie ihren State in React managen sollen. Häufig kommt die Frage nach einer offiziellen Lösung für das State-Management.[2]State management in React?

Eine weitere Frage die sich Devs seit der Einführung der Context-API und der Hooks-API in React 16.8 stellen, ist die Entscheidung zwischen Redux oder der Context-API mit useState/useReducer, um seinen globalen State zu managen.[3]Is redux really a good idea?

Beide Fragestellung möchte ich im Folgenden beantworten. Dazu habe ich in der Community recherchiert und mir die Meinung vieler erfahrener React-Entwickler eingeholt.

Was ist State Management?

Bevor wir anfangen, möchte ich aber noch Grundsätzliches klären. Bevor man die Frage nach dem richtigen State-Management lösen kann, benötigen wir meines Erachtens eine Definition was denn genau State-Management bedeutet.

Der State oder zu Deutsch Status beschreibt den Zustand einer Anwendung zu einem gegebenen Zeitpunkt.

Unterarten des States sind:

  • Server-State,
  • Navigation-State
  • lokaler UI-State
  • globaler UI-State

Dementsprechend beschreibt State-Management die Pflege des Zustands/Wissens einer Anwendung in Abhängigkeit aller Inputs.[4]Virdol, Martin – How To Simplify Your Application State Management 

Inputs finden in der Regel auf dem Server (API) oder dem Client (User) statt.

Die Schwierigkeit des State-Managements ergibt sich demnach aus der Koordination aller Unterarten des States einer Anwendung.[5]Virdol, Martin – How To Simplify Your Application State Management 

Was bedeutet State in React?

Die UI ist die optische Wiedergabe des States einer Anwendung. Wie oben beschrieben, repräsentiert der State den Zustand einer Anwendung zu einem gegebenen Zeitpunkt.[6]Wieruch, Robin -React State Management

Daraus folgt: In React der State ist eine Datenstruktur, die den aktuellen Zustand der UI widerspiegelt.

Der State kann dabei aus verschiedenartigen Daten bestehen:

  1. Ein Boolean, das entscheidet, ob eine Sidebar geöffnet ist oder nicht.
  2. Der Text-Inhalt eines Formulars.
  3. Server-Daten, die über eine API gezogen wurden.

In JavaScript können wir dies wie folgt darstellen:

// 1)
let isOpen = false;

// 2)
let addressForm = {
  first: "Donald", 
  last: "Duck",
  street: "Webfoot Walk",
  no: "1313",
  town: "Duckburg",
  state: "Calisto",
};

// 3)
const issues = [
  {
    "url": "https://api.github.com/repos/rockiger/metado/issues/47",
    "number": 47,
    "title": "Look into warnings from react beautiful dnd",
    "body": "",
    ...
  },
  ...
  {
    "url": "https://api.github.com/repos/rockiger/metado/issues/46",
    "number": 46,
    "title": "Create Testsystem for metado",
    "body": "- [ ] https://firebase.google.com/docs/emulator-suite\n",
    ...
  },
]

Alle diese Daten könnten entweder lokal (d.h. innerhalb einer Komponente mit React-Hooks oder setState) oder global gemanagt werden.

In diesem Fall bedeutet managen, das Speichern und Verändern des Status, sowie die Darstellung des Status durch die UI.

Gibt es eine offizielle / empfohlene State-Management-Lösung wie bei anderen Frameworks in React?

Jein. Es gibt mit der setState-Methode und den useState/useReducer-Hooks eine React-eigene Lösung für das lokale State Management innerhalb einer Komponente. Damit kann man schon einigermaßen komplexe Apps erstellen[7]Should I use a state management library like Redux or MobX?.

Eine quasi-offizielle Lösung für das globale State-Management wie NgRx für Angular oder Vuex für Vue gibt es nicht. Hier hat man bei React die Qual der Wahl. Manche Lösungen sind auf bestimmte Teilbereiche des Application-State spezialisiert (z.B. react-query), manche sind allgemeine Lösungen (z.B. Redux).[8]Erikon, Mark – When (and when not) to reach for Redux

Wie wählt man jetzt die passende State-Management-Lösung aus?

Navigation-State möchte ich aus dieser Betrachtung bewusst heraus lassen. Jede React-Anwendung die mehr als zwei Ansichten hat, sollte auf eine Routing-Bibliothek wie react-router setzen. Das Handling der Browser-API ist aus meiner Sicht viel zu aufwendig, um es selbst zu managen.

Wenn wir davon ausgehen, dass die Hauptschwierigkeit die Koordination der Unterarten ist, dann sollten wir uns als Erstes fragen: Welche Arten von State müssen wir in unserer (React)-Anwendung verwalten? Wie komplex ist mein State? Wie oft ändert er sich? Und dann entscheiden wir welche Lösung für uns am besten ist.

Unten seht ihr ein Diagramm meines Entscheidungsprozesses.

Entscheidungsprozess zur Auswahl des State-Management

useState

Als Erstes fragen wir uns: Wird unser State von mehr als zwei Komponenten geteilt? Wenn wir das verneinen, ist die Frage: Hat unser State eine komplexe Update-Logik, d.h. ist der neue State abhängig vom alten State oder werden mehrere Unterwerte geändert? Wenn wir auch, dies verneinen nutzen wir lokalen State mit useState.

Hat man beispielsweise einen simplen Zähler mit einer Komponente, reicht die Verwendung von lokalen State mit useState aus.

function Counter({initialCount: 42}) {
  const [count, setCount] = useState(initialCount);
  return (
    <>
      Count: {count}
      <button onClick={() => setCount(initialCount)}>Reset</button>
      <button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
      <button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
    </>
  );
}

Beim ersten Rendern der Counter-Komponente wird der useState-Hook mit intialCount initialisiert. Als Rückgabe bekommen wir die State-Variable count und die Update-Funktion setCount.

Um count zu ändern, müssen wir setCount mit einem neuen Wert aufrufen. Wann immer wir setCount aufrufen, wird die Counter-Komponente neu gerendert.

Wenn wir den neuen Wert von count auf Basis des alten setzen wollen, sollten wir setCount eine simple Update-Funktion übergeben, die als Rückgabewert den neuen Wert von count übergibt.

Aufgaben

useReducer

Wenn unser State nun aber im Gegensatz zu unserem obigen Beispiel eine komplexe Update-Logik hat, ist es sinnvoll useReducer zu verwenden.

Wie oben schon beschrieben bedeutet komplex in diesem Zusammenhang, das eine Änderung des State viele Werte des State ändern muss oder, dass der State vom vorherigen State abhängig ist.

const initialState = {count: 0};

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    case 'set':
      return {count: action.count};
    case 'reset':
      return initialState;
    default:
      state;
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'reset'})}>Reset</button>
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
      <button onClick={() => dispatch({type: 'set', count: 25})}>Set to 25</button>
    </>
  );
}

Zuerst definieren wir einen initialen State und eine pure Reducer-Funktion. Diese konsumiert einen State und eine Aktion (engl. Action) und gibt einen neuen State zurück.

Um useReducer in unsere Zähler-Komponente zu verwenden, gehen wir ähnlich vor wie mit useState: Wir initialisieren useReducer mit initalState und reducer. Nach der Initialisierung bekommen wir den State und eine Dispatch-Funktion (engl. Versand) zurück. Die Dispatch-Funktion dient dazu den Reducer mit einer State-Änderung zu beauftragen. Dazu rufen wir dispatch mit einer entsprechenden Aktion auf.

Dementsprechend enthalten die onClick-Handler der Buttons auch keine eigene Logik mehr, sondern fragen die State-Änderung nur mittels dispatch an.

Aufgaben

Context-API + State-Hooks

Wenn wir uns den rechten Teil des Entscheidungsdiagramms anschauen, also die Frage “Wird der State von mehr als zwei Komponenten geteilt?” mit Ja beantwortet haben, stehen wir vor der Frage, ob unser globaler State sich häufig ändert? Können wir diese verneinen, kann uns die Context-API das Leben erleichtern.

Ein typisches Beispiel ist der Login-Status eines Nutzers. Der in vielen unterschiedlichen Komponenten benötigt wird.

// Auth.js
const AuthContext = createContext({username: '', role: ''});

export function useAuth() {
  const context = useContext(AuthContext);
  if (!context) {
    throw new Error('useAuth must be used within a AuthProvider');
  }
  return context;
}

export function AuthProvider({ children }) {
  const [user, setUser] = useState({username: '', role: ''});

  return (
    <AuthContext.Provider value={{ user }}>
      {children}
    </AuthContext.Provider>
  );
}

// App.js
export function App() {
  return (
    <AuthProvider>
      <Component />
    </AuthProvider>
  );
}

// Component.js
export function Component() {
  const { user } = useAuth()
  if (user?.role === 'ADMIN') {
    return <AdminView />
  } else {
    return <UserView />
  }
}

In unserem Code-Beispiel initialisieren wir den Context mit createContext, den wir allen Kindern der Komponente AuthProvider zur Verfügung stellen.

Mit dem Custom-Hook useAuth können die Kind-Komponenten auf den State zugreifen. Dadurch können wir uns unnötiges Prop-Drilling ersparen.

Aufgaben

Lies mehr über Reacts useContext Hook in der React-Doku
Lies mehr über useContext kombiniert mit useState und useReducer

Server-State (react-query, Apollo, swr)

Wenn wir wieder unser Entscheidungsdiagramm anschauen, sehen wir, dass wir die Board-Mittel von React aufgebraucht haben. Wir begeben uns jetzt in den Bereich, in dem es sich lohnen kann externe State-Management-Lösungen zu verwenden.

Wenn eine Anwendung globalen State hauptsächlich dafür nutzt, um Daten die auf einem Server liegen, abzurufen, zu cachen und zu aktualisieren, empfiehlt sich eine spezialisierte Lösung zum Daten-Management zu verwenden.[9]Dodds, Kent – Application State Managment with React

In einer Admin-Oberfläche müssen wir häufig viele unterschiedliche Daten in unterschiedlichen Ansichten anzeigen. Diese Daten effizient zu managen, ist alles andere als trivial.[10]Overview react-query

Im Folgenden möchte ich ein einfaches Beispiel mit react-query zeigen.

// App.js
import { QueryClient, QueryClientProvider} from 'react-query'

const queryClient = new QueryClient()

export default function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <Component />
    </QueryClientProvider>
  )
}

// Component.js
import { useQuery } from 'react-query'

function Component() {
  const { isLoading, error, data } = useQuery('issues', () =>
    fetch('https://api.github.com/repos/rockiger/metado').then(res =>
      res.json()
    )
  )

  if (isLoading) return 'Loading...'

  if (error) return 'An error has occurred: ' + error.message

  return (
    <>
      <h1>{data.name}</h1>
      <p>{data.description}</p>
    </>
  );
}

Ähnlich wie bei unserem Context-API-Beispiel stellt uns react-query einen Context-Provider und einen Custom-Hook zur Verfügung.

Mit dem Custom-Hook useQuery können wir nun, die Daten, die wir benötigen fetchen. Dafür übergeben wir useQuery einen eindeutigen Namen und die eigentliche Fetch-Funktion. Wir bekommen dafür, die Daten (Status, Fehler, Inhalt) die wir zur Anzeige benötigen zurück.

Der eigentliche Clou ist, das react-query für uns das Management übernimmt. Es sorgt dafür, dass die Daten gecacht und automatisch aktualisiert werden. Wenn wir dieselbe Abfrage issues in einer zweiten Komponente verwenden, wird react-query die Abfrage nicht mehrmals ausführen, sondern auf die gecachten Daten zurückgreifen.[11]Important Defaults – react-query

Darüber hinaus ist der bereitgestellte Context-Provider optimiert unnötiges Neu-Rendern der Komponenten zu verhindern. Diese Funktionalität selbst zu implementieren ist alles andere als einfach.[12]On Cache Invalidation – Why is it hard?

Aufgaben

Redux et al.

Was aber macht man, wenn sich der State von mehreren Komponenten geteilt wird, sich häufig ändert und nicht hauptsächlich aus Server-State besteht?

Zum Beispiel um den State in einem Text-Editor mit vielen Schaltflächen zu managen. Hier kommt Redux ins Spiel. Redux ist sehr effizient, hat ein großes Ökosystem mit vielen Plugins (sog. Middleware) und ist sehr gut dokumentiert.

import React from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { createSlice } from '@reduxjs/toolkit'

// 1) Create state and actions/reducers
const counterSlice = createSlice({
  name: 'counter',
  initialState: {
    value: 0,
  },
  reducers: {
    incremented: (state) => {
      return {value: state.value + 1};
    },
    decremented: (state) => {
      return { value: state.value - 1 };
    },
  },
})

export const { incremented, decremented } = counterSlice.actions

// 2) select and dispatch
export const Count = () => {
  const count = useSelector(state => state.counter.count)
  const dispatch = useDispatch()

  return (
    <main>
      <div>Count: {count}</div>
      <button onClick={() => dispatch(incremented())}>Decrement</button>
      <button onClick={() => dispatch(decremented())}>Increment</button>
    </main>
  )
}

Wir reimplementieren hier wieder unser Zähler-Beispiel mithilfe von Redux und dem Redux-Toolkit. Es ist der useReducer-Variante sehr ähnlich.

Zuerst initialisieren wir unseren State und unsere Reducer. In unserer Counter-Komponente initialisieren wir einen sogenannten Selector; eine Funktion, um einen Teilbereich des State zu auswählen. Zusätzlich nutzen wir noch den useDispatch-Hook von Redux, um State-Änderungen beauftragen zu können.

Im Unterschied zu unserer useReducer-Variante müssen wir eine Action nicht mit einem String benennen. Action-Namen werden durch createSlice automatisch erzeugt.

Wie unser simples Zähler-Beispiel zeigt, erfordert die Einrichtung von Redux schon etwas mehr Aufwand. Sodass das sich der Aufwand seit der offiziellen Einführung der Context-API in React 16.3 für kleine Anwendung meistens nicht lohnt.

Die Vorteile von Redux gegenüber der Kombination aus Context-API und React-Hooks sind:[13]Erikson Marc – Blogged Answers: Redux – Not Dead Yet!

  • konsistente und definiert Architekturmuster, die die Arbeit im Team erleichtern können
  • einfaches Debugging durch die exzellente Browser-Erweiterung
  • der Einsatz von unterschiedlicher Middleware
  • viele Add-ons und eine gute Erweiterbarkeit
  • die Plattform- und Framework-übergreifende Nutzung
  • je nach App-State eine bessere Performance als die Context-API

Redux ist zwar die bekannteste und populärste State-Management-Lösung für React, aber beileibe nicht die einzige. Alternativen sind unter anderem: MobX, Recoil, RxJS.

Aufgaben

Fazit

Es muss nicht immer Redux sein. Viele React-Anwendungen kommen ohne Redux aus. In vielen Fällen führt der Einsatz von Redux zu unnötiger Komplexität.

React-Hooks und die Context-API können viele Anwendungsfälle abdecken, die früher mit Redux gelöst wurden

Für das Caching von Server-State empfiehlt sich eine spezialisierte Bibliothek.

Das Entscheidungsdiagramm kann Entwicklern helfen, die richtige Form des State-Managements für ihre Anwendung zu finden.

Abschließend sei noch gesagt, dass die gezeigten Lösungsansätze sich nicht gegenseitig ausschließen. Es spricht nichts dagegen lokalen und globalen State in seiner Anwendung zu verwenden.

Wie man sich als Solo-Gründer organisiert

Im folgenden Stelle ich euch meine tägliche Arbeitsweise vor, mit der ich zum einen meine Projekte erreiche und auch meine täglichen Aufgaben nicht aus den Augen verliere.

Problemstellung

Wenn man als Arbeitnehmer in einer Firma arbeitet, ist es normalerweise so, dass die eigenen Aufgaben klar definiert sind. In der Regel gibt es eine Projekt-Management-Software aus der klar ersichtlich ist, was als nächstes getan werden muss.

Wenn man als Freelancer, Solopreneur oder nebenberuflich tätig ist, sieht die Lage meistens anders aus.

Als ich mich mit meinen Affiliate-Websites selbstständig gemacht habe, hatte ich kein System, dem nicht folgen konnte. Ich hatte mich derzeit für ein einfaches Kanban-Board entschieden, indem ich meine Aufgaben eintrug.

Nach kurzer Zeit hatte ich Schwierigkeiten eine Balance aus neuen Features, die umgesetzt werden sollten, und regelmäßig wiederkehrenden Aufgaben zu finden.

Mein Hintergrund als Product Owner in einem Scrum-Team war mir nur bedingt hilfreich. Zwar war mir klar, wie ich Aufgaben priorisieren und abarbeiten sollte, aber ich war überfordert wiederkehrende Aufgaben einzuordnen und regelmäßig zu bearbeiten.

Also machte ich mich auf die Suche, nach Planungssystem, die mir weiterhelfen sollten. Ich interviewte Freunde und studierte mehrere Organisationssysteme und kreierte daraus mein eigenes Planungssystem.

Mein Planungssystem sollte mir mit folgenden Anforderungen weiterhelfen:

  • Wichtige Features und Aufgaben sollten hoch priorisiert sein und möglichst zeitnah umgesetzt werden.
  • Wiederkehrende Aufgaben, die regelmäßig umgesetzt werden müssen, sollten mir weder den Backlog zumüllen, noch wollte ich sie in meinem Kopf haben.
  • Darüber hinaus wollte ich, das meine notorisch überfüllte Inbox verschwindet. (In der Vergangenheit, habe ich meine Inbox gerne als Ablagesystem für später zu erledigende Aufgaben eingesetzt.)

Darf ich vorstellen: Getting Things Scrumban

Nach meinen Erfahrungen und Recherchen habe ich folgendes System entwickelt. Im Wesentlichen ist es ein uneheliches Kind aus Getting Things Done, Scrum und Kanban.

Herzstück des Systems ist wie bei den meisten agilen Projektmanagementsysteme ein Taskboard.

Aktuell gliedert sich dieses in vier Spalten: Backlog, Todo, Doing, Done. Das Taskboard ist bewusst simpel gehalten. Menschen, die häufig Aufgaben delegieren oder von anderen bei der Erledigung abhängig sind, sollten noch über eine On-Hold- oder Delegated-Spalte nachdenken.

Allerdings hilft mir das Taskboard noch nicht mit wiederkehrenden Aufgaben. Diese müssen immer wieder neu eingepflegt werden. Wenn man in Sprints arbeitet, könnte man, sobald man eine wiederkehrende Aufgabe erledigt hat, diese immer wieder neu in den Backlog einpflegen. Das finde ich aber äußerst umständlich und es entspricht auch nicht wirklich einem Backlog. Schließlich will ich meinen Backlog ja abarbeiten und nicht automatisch anwachsen lassen.

Deswegen habe ich mich neben dem Taskboard noch für eine separate Liste mit wiederkehrenden Aufgaben entschieden. Die Aufgaben in dieser Liste kennzeichnen sich dadurch, dass sie sich zum einen wie der Name schon sagt wiederholen und Arbeitsumfang begrenzt sind. Typische Einträge sind “E-Mails lesen” oder “Google Analytics checken”. Grundsätzlich ist keine wiederkehrende Aufgabe zu klein, um nicht in dieser Liste zu landen. Hauptsache die Dinge sind aus dem Kopf und belegen keine Kapazitäten im Gehirn.

Für Termine verwende ich noch einen Kalender, um meine Termine zu verwalten.

Mein Arbeitsplatz sieht in etwa so aus

My work desktop

Ablauf

Mein Tagesablauf gliedert sich wie folgt:

Als Erstes checke ich meine Termine und lese dann E-Mails und andere Nachrichten, die an mich gesendet wurden. Wenn aus diesen, neue Aufgaben hervorgehen, werden sie in den Backlog eingepflegt.

Im Anschluss verschaffe ich mir einen Überblick über mein Taskboard und die wiederkehrenden Aufgaben, die eventuell neu aufgepoppt sind. Von hier aus kann ich dann mit der Erledigung aller Tasks beginnen.

Normalerweise starte ich mit den zu wiederholenden Aufgaben, da diese schnell erledigt sind und ich dann Zeit für das Taskboard habe.

Meinen Backlog überarbeite ich mindestens einmal pro Woche. Dabei sortiere ich die Features ggf. neu und schaue, dass sie so beschrieben sind, dass ich während der Umsetzung genau weiß, was ich machen soll. Beim Scrum würde man von einem Backlog-Refinement sprechen, bei GTD von Reflect.

Alle 14 Tage mache ich eine Retrospektive, bei der ich die vergangenen 2 Wochen Revue passieren lasse, entscheide welche Arbeitsweisen gut funktioniert haben und welche ich ändern möchte, um effektiver voranzukommen.

Auf echte Sprints mit festen Scrum-Events verzichte ich, da sie nicht mit meinem aktuellen Leben vereinbar sind und ich alleine natürlich etwas flexibler bin als ein Team von 5 bis 10 Leuten.

Apps

Im Folgenden möchte ich dir noch die Tools vorstellen, die ich derzeit verwende und die gut zu mir passen.

Als To-do-Liste mit wiederholenden Aufgaben verwende ich Google Tasks. Da Google Tasks eigentlich nicht alleine in einem Browser angezeigt werden kann, habe ich mir einen kleinen Workaround geschrieben: Google Tasks im Browser. Nutzt einfach diesen Link, wenn ihr Google Tasks unabhängig von GMail oder Calendar nutzen wollt.

Als Board-Lösung nutze ich ein selbst programmiertes Tool: Metado. Der entscheidende Vorteil für mich: Metado zeigt Google Tasks und GitHub-Issues von ausgewählten Projekten an. So kann ich unterschiedliche Projekte Seite an Seite sehen, ohne sie händisch übertragen zu müssen oder mehrere Tools gleichzeitig pflegen zu müssen.

Als Kalender nutze ich Google Calendar, weil ich gerne im Google-Ökosystem arbeite.

Wer sich mit anderen Tools wohlfühlt, die für seine Zwecke besser geeignet sind, kann natürlich diese natürlich verwenden.

Nun wird es Zeit, dass ich dich zu Wort kommen lasse. Wie strukturierst du deine Arbeit? Hast du vielleicht Tipps für den Rest von uns? Teile doch deine Erkenntnisse in den Kommentaren.

Erfahrungen Dell G7 17 – 7700

Ich habe mir im April 2020 einen Dell G7 17 – 7700 zugelegt. Nach nunmehr einem halben Jahr möchte ich hier meine Erfahrungen mit diesem Laptop darstellen.

Anforderungen

Als Erstes möchte ich kurz auf meine Anforderungen eingehen. Diese waren:

  • Linux-Kompatibilität. Das Ding soll einfach laufen. Ich habe wenig Lust bei der Installation viel rum zu friemeln. Ich will Ubuntu installieren und gut.
  • Brauchbare Akkulaufzeit. Mir ist wichtig, wenn ich mal auf Reisen bin, auch im Zug ein paar Stunden arbeiten zu können. Ich brauche keinen Laptop, der einen ganzen Arbeitstag ohne Stromanschluss durchhält. Die meiste Zeit residiert mein Laptop eh auf meinem Schreibtisch.
  • Eine gute Tastatur. Wenn man schon mal mit dem Laptop direkt auf dem Schoß arbeiten muss arbeitet, dann soll die Tastatur auch angenehm zu schreiben sein. Ich persönlich mag Tastaturen mit kurzem Hub.
  • Ordentlich Speicher. Da ich beruflich viel mit React und Webpack arbeite, und dabei viele Browser Fenster offen habe, benötige ich einiges an Arbeitsspeicher. 16 GB sind eigentlich das absolute Minimum, besser sind wahrscheinlich 32 GB.
  • Große Festplatte. Ähnliches gilt für die Festplatte, am Ende sollte es wahrscheinlich ein Terabyte sein, damit man mit virtuellen Maschinen und ein paar Videos nicht gleich den ganzen Platz verbraucht.
  • 17 Zoll Display. Ich persönlich mag 17 Zoll (ca. 43 cm) Laptops. Sie ersetzen auf dem Schreibtisch einen zweiten Monitor und wenn man sie auch mal auf dem Schoß hat, machen sie einem Nacken und Schultern nicht so sehr kaputt, wie kleinere Modelle.
  • Ordentliche Verarbeitung. Eine gewisse Wertigkeit sollte der Laptop schon haben. Ich brauche kein Modell aus Vollaluminium, aber wie eine Brotdose auf dem Schulhof sollte er auch nicht so wirken.

Mit dem oben genannten Anforderungen bin ich dann erst mal auf die Suche gegangen. Die vielen günstigen Geräte, die es in der 17 Zoll Klasse gibt, schieden schon einmal aus, da Tastatur und Gehäuse meistens eine unterirdische Qualität haben.

Leider waren auch die Geräte von auf Linux spezialisierten Anbietern nichts für mich. Deren 17 Zoll Laptops sind meistens White-Label Spiele-Laptops, die sehr schwer, sehr dick, sehr teuer sind und recht billig aussehen.

Um eines klarzustellen: Ich bin großer Fan von auf Linux spezialisierten Anbietern. Einen Desktop-PC würde ich jederzeit von solch einem Anbieter kaufen. Leider bestehen Laptops nicht wie Desktop-PCs aus Standard Bauteilen, und deswegen, ist es für Nischen-Anbieter sehr schwierig eigene Laptops zu entwickeln.

Nach einiger Recherche kam ich zu der Überlegung, einen Spiele-Laptop zu kaufen, der nicht auf absolut maximale Leistung ausgelegt ist, sondern eher für Gelegenheitsspieler gedacht ist. Spiele-Laptops haben in der Regel ordentliche Hardware verbaut und besitzen eine brauchbare Tastatur, weil Spieler ja dauernd in die Tasten hacken müssen.

Ich habe mich dann für den Dell G7 17 – 7700 entschieden, weil er eine etwas erhöhtes Display hat, von dem ich mir beim Arbeiten auf dem Schoß einen kleinen Ergonomie-Vorteil versprach.

Technische Daten

Prozessor Intel Core i7-10750H 6 x 2.6 – 5 GHz (Intel Comet Lake)
Grafikkarte NVIDIA GeForce RTX 2060 Mobile – 6144 MB, GDDR6
Arbeitsspeicher 16384 MB, DDR4-2933
Display 17.30 Zoll 16:9, 1920 x 1080 Pixel 127 PPI, 9ms, entspiegelt, 144 Hz
Massenspeicher 1TB SSD
Anschlüsse 3 USB 3.0 / 3.1 Gen1, 1 Thunderbolt, 1 HDMI, 1 DisplayPort, Audio Anschlüsse: 3.5mm, Card Reader: SD
Netzwerk Killer E2500 Gigabit Ethernet Controller (10/100/1000/2500/5000MBit/s), 802.11 a/b/g/n/ac/ax (a/b/g/n = Wi-Fi 4/ac = Wi-Fi 5/ax = Wi-Fi 6), Bluetooth 5.0
Abmessungen Höhe x Breite x Tiefe (in mm): 20.7 x 398 x 290
Akku 97 Wh Lithium-Ion, 6-cell
Kamera Webcam: HD 720p
Sonstiges Lautsprecher: Stereo, Tastatur: Chiclet, Tastatur-Beleuchtung: ja
Gewicht 3.29 kg

Installation

Nach ca. 7 Tagen war der Laptop bei mir zu Hause angekommen. Als Erstes habe ich dann mit einem Live-Stick die Ubuntu-Tauglichkeit getestet. Nach ein paar Minuten ohne Probleme, bin ich dann zur Installation übergegangen. Ich habe Windows runtergeschmissen und Ubuntu 20.04 installiert.

Ich habe die Voreinstellungen des Ubuntu-Installers einfach übernommen. Brav wie ich bin, habe ich auch die Festplattenverschlüsselung angestellt.

Nach kurzer Zeit war die Installation fix und fertig. Der G7 und war somit einsatzbereit und konnte auch schon gut verwendet werden.

Am BIOS habe ich übrigens nichts geändert, sondern die Werkseinstellungen gelassen wie sie sind.

Nacharbeiten

Wo viel Licht ist, da ist auch Schatten. Zwar konnte man mit dem G7 nach der Ubuntu-Installation direkt loslegen und arbeiten. Aber nichtsdestotrotz gab es ein paar Kleinigkeiten, die es zu optimieren galt.

Der vom Ubuntu-Installer standardmäßig installierte Nvidia-Treiber funktionierte mit meinem Multi-Monitor Setup nicht. Ich habe meinem Arbeitsplatz neben dem Laptop Monitor noch zwei weitere Monitore die ich einmal per USB und einmal per HDMI anspreche. Mit dem proprietären Nvidia-Treiber hat es schlicht nicht funktioniert, mehr als einen Monitor anzusprechen.

Da Spielen für mich keine Priorität hat, habe ich mich nach anderen Lösungen umgeschaut. Meine erste Idee war es auf den quelloffenen Nouveau-Treiber zu setzen. Und zu meinem Glück funktionierte diese auch direkt. Sein Vorteil ist, dass er sich wesentlich besser in die Ubuntu-/Gnome-Settings einfügt.

Die schlechtere Performance bei grafiklastigen Anwendungen spielt für mich keine große Rolle

Neben den Problemen mit der Grafikkarte hakte nur der Fingerprint-Reader. Um den habe ich mich aber nicht weiter gekümmert.

Bildschirm

Der Full HD Bildschirm ist sehr hell und man kann damit problemlos auch in der Sonne arbeiten. Die maximale Auflösung liegt bei 1920 x 1080.

Batterielaufzeit

Mit der Batterielaufzeit bin ich durchaus zufrieden. Für eine Bahnreise reicht es allemal. Ich muss meinen Laptop nicht den ganzen Tag nutzen können, ohne ihn laden. 5 bis 6 Stunden sind bei normaler Benutzung allemal drin.

Tastatur & Touchpad

Tastatur und Touchpad sind die heimlichen Highlights des G7. Der Tastenhub ist sehr gering, was ich persönlich mag, und funktioniert butterweich.

Das große Touchpad ist aus Glas und lässt sich sehr angenehm nutzen. Anders als bei billigen Laptops gleitet man sehr leicht über die Oberfläche. Die Multitouch Unterstützung mit Ubuntu ist zumindest für meine ansprechen Ansprüche ausreichen.

Fazit

Abschließend muss ich sagen, dass ich mit dem G7 sehr zufrieden bin. Es war für mich ein echter Glücksgriff. Das Gerät ist leistungsfähig genug, sieht gut aus und hat eine sehr gute Ergonomie.

Creative WP-300 Bluetooth-Kopfhörer mit Ubuntu

Ich habe den Creative WP-300 Bluetooth-Kopfhörer zum Geburtstag geschenkt bekommen. Und möchte hier meine Erfahrungen wiedergeben wie der Bluetooth-Kopfhörer mit Ubuntu funktioniert.

Kopfhörer an Ubuntu-Laptop anschließen

Den Kopfhörer mit meinem SatchBook zu verbinden, war völlig problemlos.Um den Kopfhörer an euren Laptop oder PC anzuschließen, müsst ihr:

  1. natürlich als erstes Bluetooth bei eurem Laptop aktivieren
  2. dann aktiviert ihr den Kopfhörer, durch 5 Sekunden drücken der Power-Taste
  3. im Bluetooth-Menü von Ubuntu "Neues Gerät konfigurieren…" wählen und dem Dialog folgen.

Weiter Informationen zum Thema Ubuntu und Bluetooth findet ihr auf ubuntuusers.de.

Erfahrung im Betrieb

Das wichtigste zuerst – die Tonqualität:

Das Klangerlebnis ist aus meiner Sicht 1. Sahne. Allerdings muss ich sagen, ich bin kein Soundfetischist und habe auch noch nie wirklich teure Kopfhörer benutzt. Aber zu meinem Philips SHP 1900 Stereokopfhörern und meinem Logitech H390 USB-Headset, ist die Steigerung der Soundqualität riesig.

Der Empfang:

In meiner Altbau-Wohnung habe ich Empfang bis zu 5 Meter – dann bekommt das Signal Störungen. Allerdings muss man sagen, dass die Wohnung ca. 100 Jahre alt ist und über extrem dicke Wände verfügt. Wie weit der Empfang im Freien ist, weiß ich nicht so genau, da ich mein SatchBook immer am Körper bzw. im Rucksack trage. Es gab zumindest noch keine Probleme.

Steuerungs-/Funktions-Tasten

Mit Banshee funktionieren die Steuerungs-Tasten für Play/Pause, Zurück und Vorwärts absolut problemlos. Andere Mediaplayer für Ubuntu habe ich noch nicht getestet. Kleiner Tip: das Soundmenü von Ubuntu darf nicht geöffnet sein, sonst blockiert es die Steuerungstasten des Bluetooth-Kopfhörers.

Verbinden:

Wenn ihr die Kopfhörer wie oben beschrieben mit Ubuntu konfiguriert habt, erkennt Ubuntu die Kopfhörer sobald ihr sie aktiviert habt und Bluetooth an eurem Laptop aktiviert ist. Falls das mal nicht funktionieren sollte, müsst ihr im Bluetooth-Menü das Creative WP-300 Headphones anwählen und auf Verbinden… klicken. Falls Banshee schon läuft, kommt es manchmal vor, dass die Wiedergabe stoppt, dann reicht es aus einfach auf die Play-Taste zu drücken. Fragt mich bitte nicht, warum das so ist.

Ein zweites Problem, dass auftreten kann ist: Das Ubuntu nicht auf den Bluetooth-Kopfhörer schaltet, sondern die Lautsprecher des Laptops aktiviert bleiben. Dann müsst ihr im Sound-Menü auf Audio-Einstellung… und im Reiter Ausgabe das Creative WP-300 Headphones auswählen.

Fazit: Creative WP-300 Bluetooth-Kopfhörer unter Ubuntu

Ich für meinen Teil, bin begeistert vom Creative WP-300 Bluetooth-Kopfhörer. Speziell das Zusammenspiel mit Ubuntu hat mich positiv überrascht; ich habe mit Schlimmerem gerechnet.

Verkauft Produkte statt Arbeitskraft

Tipp Existensgründer

Mein wichtigster Tipp für Existenzgründer: Verkauft nicht eure Arbeitskraft, sondern verkauft ein Produkt! Im Rahmen dieses Artikels nehme ich an der Blog-Parade von Gründungswissen.at teil.

Besser angestellt sein, als seine Arbeitskraft zu verkaufen!

Viele Existenzgründer bieten einfach ihre Arbeitskraft zum Verkauf an z.B. eine selbstständige Putzfrau sein oder ein Unternehmensberater. Dieses Konzept hat einen Makel: Es skaliert nicht, birgt aber trotzdem hohes Risiko. Man hat die Nachteile eines Entrepreneurs, aber nicht die gleichen Wachstumsmöglichkeiten. Anders gesagt, man sollte besser eine Stelle suchen und an einem Arbeitgeber seine Arbeitskraft verkaufen.

Wenn ein "Arbeitskraftverkäufer" sein Einkommen verbessern will hat er zwei Möglichkeiten:

  1. Er arbeitet mehr.
  2. Er erhöht den Preis.

Beides ist in der Regel beschränkt. Mehr als 24 Stunden kann man nicht arbeiten und die Kunden zahlen meistens auch nicht jeden Preis. In der Praxis wird meistens eine Mischung aus beidem gemacht: Man arbeitet wie bekloppt und versucht den Preis zu erhöhen.

Die Lösung: ein Produkt verkaufen

Existenzgründer TippWas also machen? Produkte verkaufen. Das können eigens entwickelte Produkte sein oder Produkte, mit welchen man einfach nur handelt. Der Vorteil: Wenn die Nachfrage steigt, kann man einfach mehr verkaufen – das Geschäftsmodell skaliert.

Übrigens, mit Produkten meine ich nicht nur klassische Industrie-Güter, sondern auch Dienstleistungen, Franchisesysteme u.ä.

Wie findet man ein Produkt, dass nachgefragt wird?

Der Erfinder des Management, Peter Drucker, hat eine Liste mit 7 Quellen für innovative Ideen aufgestellt, die ich in einer Übersicht zusammengefasst habe. Diese sind ein guter Anfang, um nach Marktlücken zu suchen.

Ich bin mal gespannt, ob mein wichtigster Tipp für Existenzgründer euch in Zukunft weiterhilft. Wie immer freue ich mich über Anregungen und Kritik.

Ubuntu-Linux 10.04 auf dem Laptop: Optimieren

Im letzten Artikel "Ubuntu-Linux 10.04 auf dem Laptop: Installieren" habe ich dir gezeigt, wie du Ubuntu-Linux installierst; heute zeige ich dir: wie du es optimierst, damit alles reibungslos läuft.

1. Automatisches Entsperren des Schlüsselbundes

Wenn du bei der Installation die automatische Anmeldung ausgewählt hast, solltest du noch dafür Sorgen, dass der Schlüsselbund deines Ubuntu-Linux sich auch automatisch entsperrt; sonst musst du nämlich diesen per Hand entsperren, wenn du z.B. dein WLAN verbinden willst, und führst somit die automatische Anmeldung ad absurdum.

Ubuntu-Linux Optimierung: Terminal starten

Um den den Schlüsselbund automatisch zu entsperren, musst du folgendes tun: Alt + F2 drücken, in das Feld "gnome-terminal" eingeben und Enter drücken; in dem neuen Fenster (einem Terminal) gibst du ein:

rm -r ~/.gnome2/keyrings
sudo reboot
[Dein Passwort]

Ubuntu-Linux Optimierung: Keyring löschen

Der Computer macht jetzt einen Neustart; wenn der Computer wieder hochgefahren ist, musst du dein WLAN-Passwort leider nocheinmal eingeben.

Ubuntu-Linux Optimierung: WLAN Passwort eingeben

Dass Passwort für den neuen Schlüsselbund lässt du jetzt leer und bestätigst auch die "unsichere Speicherung verwenden".

Bitte beachte: Deine Passwörter werden jetzt nicht mehr verschlüsselt; das stellt ein potentielles Sicherheitsrisiko dar.

Mehr zum Thema Schlüsselbund und sudo erfährst du bei Ubuntuusers.de.

2. Ubuntu Bildschirmschoner anpassen

Ubuntu-Linux Optimierung: Bildschirmschoner abschalten

Um Strom zu sparen solltest du den Bildschirmschoner ausschalten; außerdem nervt es tierisch wenn schon nach kurzen Abständen der Bildschirm gesperrt ist – das kannst natürlich anders sehen 🙂 Wenn du, wie ich, den Bildschirmschoner abschallten willst, klicke in der Menü-Leiste von Ubuntu auf "System > Einstellungen > Bildschirm"; entferne die Häkchen im Dialog je nach Belieben und wähle als Bildschirnschoner-Thema "Leerer Bildschirm".

3. Energiesparoptionen für den Laptop richtig einstellen

In der Menü-Leiste "System > Einstellungen > Energieverwaltung" klicken; dann geht's weiter zum Reiter "Im Akkubetrieb".

Ubuntu-Linux Optimierung: Energieverwaltung einstellen

Im obersten Auswahlfeld 10 Minuten auswählen; "Beim Schließen des Deckels" wähle ich "Bildschirm abdunkeln" – so kann ich meinen Ubuntu-Laptop als mobilen MP3-Player für Parties verwenden. Sonst kannst du alle Einstellungen so lassen wie sie sind.

4. Wichtige Ubuntu-Paketquellen aktivieren

Um weitere Quellen für Software-Programme zu aktivieren, öffnest du ein Terminal – na weisst ihr noch wie es geht? Alt + F2 drücken und dann "gnome-terminal" eingeben; im Terminal gibst du folgendes ein – am besten mit Copy & Paste:

sudo wget --output-document=/etc/apt/sources.list.d/medibuntu.list http://www.medibuntu.org/sources.list.d/$(lsb_release -cs).list && sudo apt-get --quiet update && sudo apt-get --yes --quiet --allow-unauthenticated install medibuntu-keyring && sudo apt-get --quiet update

sudo apt-get --yes install app-install-data-medibuntu apport-hooks-medibuntu

Du wirst im Terminal noch nach deinem Passwort gefragt. Nun werden die Medibuntu-Paketquellen auf deinem Ubuntu-Laptop installiert und aktualisiert – das dauert ein wenig, aber die Medibuntu-Pakete sind für viele Multimedia-Anwendungen wichtig.

5. Multimedia-Pakete installieren

Da du die Medibuntu-Paketquellen installiert hast, solltest du auch Software daraus installieren; im immer noch offenen Terminal gibst du folgendes ein:

sudo apt-get install libdvdcss2 ubuntu-restricted-extras w32codecs

Nach ein paar Minuten hast du alles installiert was du für Ton und Bild so brauchst.

6. Pakete installieren um Quellcode zu übersetzen

Abschließend empfehle ich dir noch die so genannten "build-essentials" zu installieren; diese sind zwar nicht notwendig, aber früher oder später brauchst du sie bestimmt und dann bist du froh wenn du sie schon installiert hast:

sudo apt-get install build-essential

Jetzt sollte dein Ubuntu-Laptop für alles gerüstet sein, was in der Ubuntu-Linux-Welt so auf dich zukommt.

Ubuntu-Linux Optimierung: Multimedia Pakete installieren

Im letzten Teil meiner Artikelserie "Ubuntu-Linux 10.04 auf dem Laptop: Programme" stelle ich dir noch meine Lieblingsprogramme vor, die mich bei der täglichen Arbeit mit Linux unterstützen.

Schneller mit Ubuntu Teil 3: Parcellite

Ihr kennt bestimmt alle die Tastenkombinationen <Strg>+c, <Strg>+v und <Strg>+x um Inhalte in die Zwischenablage zu kopieren. Wenn nicht, solltet ihr das aber schnellstens nachholen. Der große Nachteil der Standard-Zwischenablage ist, dass, wenn man mehrere Textstellen kopieren will, man immer zwischen der Quell- und Zielanwendung hin- und herspringen muss. Parcellite legt für euch einen Verlauf der Zwischenablage an.

Installieren

Ladet euch das Paket runter und installiert es mit dem GDebi-Installer. Auch hier ist es am besten ihr legt auch gleich einen Autostarteintrag an.

Benutzen

Mit einem Klick auf das Applet oder die Tastenkombinationen <Strg>+<Alt>+h könnt ihr euch die letzten 25 Einträge anzeigen lassen und einen auswählen.

Ihr könnt den Eintrag dann, wie gewohnt mit <Strg>+v einfügen. Ein typischer Anwendungsfall ist z. B., wenn ihre eine bestimmte Textstelle immer mal wieder benötigt und trotzdem die restliche Zeit, wie gewohnt weiterarbeiten wollt. So müsst ihr nicht immer wieder auf die ursprüngliche Quelle zurück, sondern wählt einfach den gewünschten Eintrag im Zwischenablagenverlauf an. Es dauert ein wenig, bis man sich an Parcellite gewöhnt hat und es effektiv verwendet.