Skip to content

Commit

Permalink
Update PilotsList to be connected
Browse files Browse the repository at this point in the history
Connected the PilotsList and PilotsListRow components
PilotsList now extracts a list of pilot IDs instead of objects
Disconnected Pilots, which is now effectively presentational again
  • Loading branch information
markerikson committed Oct 29, 2017
1 parent 9fbb8b9 commit 871a01f
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 75 deletions.
70 changes: 3 additions & 67 deletions src/features/pilots/Pilots.jsx
@@ -1,76 +1,16 @@
import React, {Component} from "react";
import {connect} from "react-redux";

import {
Grid,
Segment,
Header,
} from "semantic-ui-react";

import orm from "app/orm";

import PilotsList from "./PilotsList";
import PilotDetails from "./PilotDetails";

import {selectPilot} from "./pilotsActions";
import {selectCurrentPilot} from "./pilotsSelectors";


const mapState = (state) => {
// Create a Redux-ORM Session from our "entities" slice, which
// contains the "tables" for each model type
const session = orm.session(state.entities);

// Retrieve the model class that we need. Each Session
// specifically "binds" model classes to itself, so that
// updates to model instances are applied to that session.
// These "bound classes" are available as fields in the sesssion.
const {Pilot} = session;

// Query the session for all Pilot instances.
// The QuerySet that is returned from all() can be used to
// retrieve instances of the Pilot class, or retrieve the
// plain JS objects that are actually in the store.

// The toModelArray() method will give us an array of the
// Model class instances objects for each item in the QuerySet.
const pilots = Pilot.all().toModelArray().map(pilotModel => {
// Access the underlying plain JS object using the "ref" field,
// and make a shallow copy of it
const pilot = {
...pilotModel.ref
};

// We want to look up pilotModel.mech.mechType. Just in case the
// relational fields are null, we'll do a couple safety checks as we go.

// Look up the associated Mech instance using the foreign-key
// field that we defined in the Pilot Model class
const {mech} = pilotModel;

// If there actually is an associated mech, include the
// mech type's ID as a field in the data passed to the component
if(mech && mech.type) {
pilot.mechType = mech.type.id;
}

return pilot;
});

const currentPilot = selectCurrentPilot(state);

// Now that we have an array of all pilot objects, return it as a prop
return {pilots, currentPilot};
}

// Make an object full of action creators that can be passed to connect
// and bound up, instead of writing a separate mapDispatch function
const actions = {
selectPilot,
};


export class Pilots extends Component {
class Pilots extends Component {
render() {
const {pilots = [], selectPilot, currentPilot} = this.props;

Expand All @@ -79,11 +19,7 @@ export class Pilots extends Component {
<Grid>
<Grid.Column width={10}>
<Header as="h3">Pilot List</Header>
<PilotsList
pilots={pilots}
onPilotClicked={selectPilot}
currentPilot={currentPilot}
/>
<PilotsList />
</Grid.Column>
<Grid.Column width={6}>
<Header as="h3">Pilot Details</Header>
Expand All @@ -97,4 +33,4 @@ export class Pilots extends Component {
}
}

export default connect(mapState, actions)(Pilots);
export default Pilots;
56 changes: 49 additions & 7 deletions src/features/pilots/PilotsList/PilotsList.jsx
@@ -1,20 +1,61 @@
import React, {Component} from "react";
import {connect} from "react-redux";
import {Table} from "semantic-ui-react";

import PilotsListHeader from "./PilotsListHeader";
import PilotsListRow from "./PilotsListRow";

import orm from "app/orm";

export default class PilotsList extends Component {
import {selectPilot} from "../pilotsActions";
import {selectCurrentPilot} from "../pilotsSelectors";


const mapState = (state) => {
// Create a Redux-ORM Session from our "entities" slice, which
// contains the "tables" for each model type
const session = orm.session(state.entities);

// Retrieve the model class that we need. Each Session
// specifically "binds" model classes to itself, so that
// updates to model instances are applied to that session.
// These "bound classes" are available as fields in the sesssion.
const {Pilot} = session;

// Query the session for all Pilot instances.
// The QuerySet that is returned from all() can be used to
// retrieve instances of the Pilot class, or retrieve the
// plain JS objects that are actually in the store.

// The withModels modifier will let us map over Model instances
// for each entry, rather than the plain JS objects.

// Extract a list of IDs for all
const pilots = Pilot.all().toModelArray().map(pilotModel => pilotModel.getId());

This comment has been minimized.

Copy link
@sp-luciano-chinke

sp-luciano-chinke May 16, 2021

We could improve it with something like this, right? 🤔
const pilots = state.entities.Pilot.items;


const currentPilot = selectCurrentPilot(state);

// Now that we have an array of all pilot objects, return it as a prop
return {pilots, currentPilot};
}

// Make an object full of action creators that can be passed to connect
// and bound up, instead of writing a separate mapDispatch function
const actions = {
selectPilot,
};


export class PilotsList extends Component {
render() {
const {pilots, onPilotClicked, currentPilot} = this.props;
const {pilots, selectPilot, currentPilot} = this.props;

const pilotRows = pilots.map(pilot => (
const pilotRows = pilots.map(pilotID => (
<PilotsListRow
pilot={pilot}
key={pilot.name}
onPilotClicked={onPilotClicked}
selected={pilot.id === currentPilot}
pilotID={pilotID}
key={pilotID}
onPilotClicked={selectPilot}
selected={pilotID === currentPilot}
/>
));

Expand All @@ -29,3 +70,4 @@ export default class PilotsList extends Component {
}
}

export default connect(mapState, actions)(PilotsList);
37 changes: 36 additions & 1 deletion src/features/pilots/PilotsList/PilotsListRow.jsx
@@ -1,7 +1,42 @@
import React from "react";
import {connect} from "react-redux";
import {Table} from "semantic-ui-react";
import _ from "lodash";

import orm from "app/orm";

const mapState = (state, ownProps) => {
const session = orm.session(state.entities);
const {Pilot} = session;

let pilot;

if(Pilot.hasId(ownProps.pilotID)) {
const pilotModel = Pilot.withId(ownProps.pilotID);

// Access the underlying plain JS object using the "ref" field,
// and make a shallow copy of it
pilot = pilot = {
...pilotModel.ref
};

// We want to look up pilotModel.mech.mechType. Just in case the
// relational fields are null, we'll do a couple safety checks as we go.

// Look up the associated Mech instance using the foreign-key
// field that we defined in the Pilot Model class
const {mech} = pilotModel;

// If there actually is an associated mech, include the
// mech type's ID as a field in the data passed to the component
if(mech && mech.type) {
pilot.mechType = mech.type.id;
}
}

return {pilot};
}

const PilotsListRow = ({pilot={}, onPilotClicked=_.noop, selected}) => {
const {
id = null,
Expand Down Expand Up @@ -34,4 +69,4 @@ const PilotsListRow = ({pilot={}, onPilotClicked=_.noop, selected}) => {
);
}

export default PilotsListRow;
export default connect(mapState)(PilotsListRow);

0 comments on commit 871a01f

Please sign in to comment.