Last active
September 20, 2019 16:12
-
-
Save joemaffei/87d864d5602d00de2a5acc40642686b8 to your computer and use it in GitHub Desktop.
Refactoring React: reducer helper function
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Original | |
function clearTempStatuses(state) { | |
if (state == null) return []; | |
return state.map((quote) => { | |
const options = quote.options.map((option) => { | |
const { tempStatus: optionTempStatus, ...optionWithoutTempStatus } = option; | |
if (optionTempStatus) { | |
return { ...optionWithoutTempStatus, status: optionTempStatus }; | |
} | |
return optionWithoutTempStatus; | |
}); | |
const { tempStatus: quoteTempStatus, ...quoteWithoutTempStatus } = quote; | |
const newQuote = { ...quoteWithoutTempStatus, options: options }; | |
if (quoteTempStatus) { | |
return { ...newQuote, status: quoteTempStatus }; | |
} | |
return newQuote; | |
}); | |
} | |
// 1. "state" can be confusing. This is manipulating data for the "quotes" reducer. | |
function clearTempStatuses(quotes) { | |
if (quotes == null) return []; | |
return quotes.map((quote) => { | |
const options = quote.options.map((option) => { | |
const { tempStatus: optionTempStatus, ...optionWithoutTempStatus } = option; | |
if (optionTempStatus) { | |
return { ...optionWithoutTempStatus, status: optionTempStatus }; | |
} | |
return optionWithoutTempStatus; | |
}); | |
const { tempStatus: quoteTempStatus, ...quoteWithoutTempStatus } = quote; | |
const newQuote = { ...quoteWithoutTempStatus, options: options }; | |
if (quoteTempStatus) { | |
return { ...newQuote, status: quoteTempStatus }; | |
} | |
return newQuote; | |
}); | |
} | |
// 2. remove temporary options variable | |
function clearTempStatuses(quotes) { | |
if (quotes == null) return []; | |
return quotes.map((quote) => { | |
const { tempStatus: quoteTempStatus, ...quoteWithoutTempStatus } = quote; | |
const newQuote = { ...quoteWithoutTempStatus, options: quote.options.map((option) => { | |
const { tempStatus: optionTempStatus, ...optionWithoutTempStatus } = option; | |
if (optionTempStatus) { | |
return { ...optionWithoutTempStatus, status: optionTempStatus }; | |
} | |
return optionWithoutTempStatus; | |
})}; | |
if (quoteTempStatus) { | |
return { ...newQuote, status: quoteTempStatus }; | |
} | |
return newQuote; | |
}); | |
} | |
// 3. multiline returned objects for clarity | |
function clearTempStatuses(quotes) { | |
if (quotes == null) return []; | |
return quotes.map((quote) => { | |
const { tempStatus: quoteTempStatus, ...quoteWithoutTempStatus } = quote; | |
const newQuote = { | |
...quoteWithoutTempStatus, | |
options: quote.options.map((option) => { | |
const { tempStatus: optionTempStatus, ...optionWithoutTempStatus } = option; | |
if (optionTempStatus) { | |
return { | |
...optionWithoutTempStatus, | |
status: optionTempStatus, | |
}; | |
} | |
return optionWithoutTempStatus; | |
}) | |
}; | |
if (quoteTempStatus) { | |
return { ...newQuote, status: quoteTempStatus }; | |
} | |
return newQuote; | |
}); | |
} | |
// 4. destructure object properties in function declarations | |
function clearTempStatuses(quotes) { | |
if (quotes == null) return []; | |
return quotes.map(({ tempStatus: quoteTempStatus, options, ...quoteWithoutTempStatus }) => { | |
const newQuote = { | |
...quoteWithoutTempStatus, | |
options: options.map(({ tempStatus: optionTempStatus, ...optionWithoutTempStatus }) => { | |
if (optionTempStatus) { | |
return { | |
...optionWithoutTempStatus, | |
status: optionTempStatus, | |
}; | |
} | |
return optionWithoutTempStatus; | |
}) | |
}; | |
if (quoteTempStatus) { | |
return { ...newQuote, status: quoteTempStatus }; | |
} | |
return newQuote; | |
}); | |
} | |
// 5. move condition in options.map callback to the returned object (which requires destructuring `status`) | |
function clearTempStatuses(quotes) { | |
if (quotes == null) return []; | |
return quotes.map(({ tempStatus: quoteTempStatus, options, ...quoteWithoutTempStatus }) => { | |
const newQuote = { | |
...quoteWithoutTempStatus, | |
options: options.map(({ tempStatus: optionTempStatus, status: optionStatus, ...optionWithoutTempStatus }) => { | |
return { | |
...optionWithoutTempStatus, | |
status: optionTempStatus || optionStatus, | |
}; | |
}) | |
}; | |
if (quoteTempStatus) { | |
return { ...newQuote, status: quoteTempStatus }; | |
} | |
return newQuote; | |
}); | |
} | |
// 6. do the same thing for the quotes.map callback | |
function clearTempStatuses(quotes) { | |
if (quotes == null) return []; | |
return quotes.map(({ tempStatus: quoteTempStatus, options, status: quoteStatus, ...quoteWithoutTempStatus }) => { | |
const newQuote = { | |
...quoteWithoutTempStatus, | |
options: options.map(({ tempStatus: optionTempStatus, status: optionStatus, ...optionWithoutTempStatus }) => { | |
return { | |
...optionWithoutTempStatus, | |
status: optionTempStatus || optionStatus, | |
}; | |
}) | |
}; | |
return { | |
...newQuote, | |
status: quoteTempStatus || quoteStatus, | |
}; | |
}); | |
} | |
// 7. remove temporary newQuote variable | |
function clearTempStatuses(quotes) { | |
if (quotes == null) return []; | |
return quotes.map(({ tempStatus: quoteTempStatus, options, status: quoteStatus, ...quoteWithoutTempStatus }) => { | |
return { | |
...quoteWithoutTempStatus, | |
options: options.map(({ tempStatus: optionTempStatus, status: optionStatus, ...optionWithoutTempStatus }) => { | |
return { | |
...optionWithoutTempStatus, | |
status: optionTempStatus || optionStatus, | |
}; | |
}), | |
status: quoteTempStatus || quoteStatus, | |
}; | |
}); | |
} | |
// 8. extract callbacks into function declarations | |
function clearTempStatuses(quotes) { | |
if (quotes == null) return []; | |
function quotesMapCallback({ | |
tempStatus: quoteTempStatus, | |
options, | |
status: quoteStatus, | |
...quoteWithoutTempStatus | |
}) { | |
return { | |
...quoteWithoutTempStatus, | |
options: options.map(optionsMapCallback), | |
status: quoteTempStatus || quoteStatus, | |
}; | |
} | |
function optionsMapCallback({ | |
tempStatus: optionTempStatus, | |
status: optionStatus, | |
...optionWithoutTempStatus | |
}) { | |
return { | |
...optionWithoutTempStatus, | |
status: optionTempStatus || optionStatus, | |
}; | |
} | |
return quotes.map(quotesMapCallback); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment