Merge pull request #3599 from owenconti/ft/3598-responses-shouldComponentUpdate

shouldComponentUpdate for response components
This commit is contained in:
kyle
2017-09-29 13:58:55 -07:00
committed by GitHub
8 changed files with 65 additions and 36 deletions

View File

@@ -1,6 +1,7 @@
import React from "react" import React from "react"
import PropTypes from "prop-types" import PropTypes from "prop-types"
import ImPropTypes from "react-immutable-proptypes" import ImPropTypes from "react-immutable-proptypes"
import { Iterable } from "immutable"
const Headers = ( { headers } )=>{ const Headers = ( { headers } )=>{
return ( return (
@@ -28,19 +29,29 @@ Duration.propTypes = {
export default class LiveResponse extends React.Component { export default class LiveResponse extends React.Component {
static propTypes = { static propTypes = {
response: PropTypes.object.isRequired, response: PropTypes.instanceOf(Iterable).isRequired,
specSelectors: PropTypes.object.isRequired, path: PropTypes.string.isRequired,
pathMethod: PropTypes.object.isRequired, method: PropTypes.string.isRequired,
getComponent: PropTypes.func.isRequired,
displayRequestDuration: PropTypes.bool.isRequired, displayRequestDuration: PropTypes.bool.isRequired,
specSelectors: PropTypes.object.isRequired,
getComponent: PropTypes.func.isRequired,
getConfigs: PropTypes.func.isRequired getConfigs: PropTypes.func.isRequired
} }
shouldComponentUpdate(nextProps) {
// BUG: props.response is always coming back as a new Immutable instance
// same issue as responses.jsx (tryItOutResponse)
return this.props.response !== nextProps.response
|| this.props.path !== nextProps.path
|| this.props.method !== nextProps.method
|| this.props.displayRequestDuration !== nextProps.displayRequestDuration
}
render() { render() {
const { response, getComponent, getConfigs, displayRequestDuration, specSelectors, pathMethod } = this.props const { response, getComponent, getConfigs, displayRequestDuration, specSelectors, path, method } = this.props
const { showMutatedRequest } = getConfigs() const { showMutatedRequest } = getConfigs()
const curlRequest = showMutatedRequest ? specSelectors.mutatedRequestFor(pathMethod[0], pathMethod[1]) : specSelectors.requestFor(pathMethod[0], pathMethod[1]) const curlRequest = showMutatedRequest ? specSelectors.mutatedRequestFor(path, method) : specSelectors.requestFor(path, method)
const status = response.get("status") const status = response.get("status")
const url = response.get("url") const url = response.get("url")
const headers = response.get("headers").toJS() const headers = response.get("headers").toJS()
@@ -111,7 +122,6 @@ export default class LiveResponse extends React.Component {
static propTypes = { static propTypes = {
getComponent: PropTypes.func.isRequired, getComponent: PropTypes.func.isRequired,
request: ImPropTypes.map,
response: ImPropTypes.map response: ImPropTypes.map
} }
} }

View File

@@ -6,6 +6,8 @@ import { Iterable } from "immutable"
export default class Operation extends PureComponent { export default class Operation extends PureComponent {
static propTypes = { static propTypes = {
operation: PropTypes.instanceOf(Iterable).isRequired, operation: PropTypes.instanceOf(Iterable).isRequired,
response: PropTypes.instanceOf(Iterable),
request: PropTypes.instanceOf(Iterable),
toggleShown: PropTypes.func.isRequired, toggleShown: PropTypes.func.isRequired,
onTryoutClick: PropTypes.func.isRequired, onTryoutClick: PropTypes.func.isRequired,
@@ -25,19 +27,21 @@ export default class Operation extends PureComponent {
} }
static defaultProps = { static defaultProps = {
showSummary: true, operation: null,
response: null, response: null,
allowTryItOut: true, request: null
displayOperationId: false,
displayRequestDuration: false
} }
shouldComponentUpdate(nextProps) { shouldComponentUpdate(nextProps) {
return this.props.operation !== nextProps.operation return this.props.operation !== nextProps.operation
|| this.props.response !== nextProps.response
|| this.props.request !== nextProps.request
} }
render() { render() {
let { let {
response,
request,
toggleShown, toggleShown,
onTryoutClick, onTryoutClick,
onCancelClick, onCancelClick,
@@ -69,8 +73,6 @@ export default class Operation extends PureComponent {
tryItOutEnabled, tryItOutEnabled,
executeInProgress executeInProgress
} = operationProps.toJS() } = operationProps.toJS()
let response = operationProps.get("response")
let request = operationProps.get("request")
let { let {
summary, summary,
@@ -216,7 +218,8 @@ export default class Operation extends PureComponent {
specActions={ specActions } specActions={ specActions }
produces={ produces } produces={ produces }
producesValue={ operation.get("produces_value") } producesValue={ operation.get("produces_value") }
pathMethod={ [path, method] } path={ path }
method={ method }
displayRequestDuration={ displayRequestDuration } displayRequestDuration={ displayRequestDuration }
fn={fn} /> fn={fn} />
} }

View File

@@ -1,7 +1,7 @@
import React from "react" import React from "react"
import PropTypes from "prop-types" import PropTypes from "prop-types"
import cx from "classnames" import cx from "classnames"
import { fromJS, Seq } from "immutable" import { fromJS, Seq, Iterable } from "immutable"
import { getSampleSchema, fromJSOrdered } from "core/utils" import { getSampleSchema, fromJSOrdered } from "core/utils"
const getExampleComponent = ( sampleResponse, examples, HighlightCode ) => { const getExampleComponent = ( sampleResponse, examples, HighlightCode ) => {
@@ -42,7 +42,7 @@ export default class Response extends React.Component {
static propTypes = { static propTypes = {
code: PropTypes.string.isRequired, code: PropTypes.string.isRequired,
response: PropTypes.object, response: PropTypes.instanceOf(Iterable),
className: PropTypes.string, className: PropTypes.string,
getComponent: PropTypes.func.isRequired, getComponent: PropTypes.func.isRequired,
specSelectors: PropTypes.object.isRequired, specSelectors: PropTypes.object.isRequired,
@@ -57,6 +57,12 @@ export default class Response extends React.Component {
onContentTypeChange: () => {} onContentTypeChange: () => {}
}; };
shouldComponentUpdate(nextProps) {
return this.props.code !== nextProps.code
|| this.props.response !== nextProps.response
|| this.props.className !== nextProps.className
}
_onContentTypeChange = (value) => { _onContentTypeChange = (value) => {
const { onContentTypeChange, controlsAcceptHeader } = this.props const { onContentTypeChange, controlsAcceptHeader } = this.props
this.setState({ responseContentType: value }) this.setState({ responseContentType: value })

View File

@@ -4,38 +4,49 @@ import { fromJS, Iterable } from "immutable"
import { defaultStatusCode, getAcceptControllingResponse } from "core/utils" import { defaultStatusCode, getAcceptControllingResponse } from "core/utils"
export default class Responses extends React.Component { export default class Responses extends React.Component {
static propTypes = { static propTypes = {
request: PropTypes.instanceOf(Iterable),
tryItOutResponse: PropTypes.instanceOf(Iterable), tryItOutResponse: PropTypes.instanceOf(Iterable),
responses: PropTypes.instanceOf(Iterable).isRequired, responses: PropTypes.instanceOf(Iterable).isRequired,
produces: PropTypes.instanceOf(Iterable), produces: PropTypes.instanceOf(Iterable),
producesValue: PropTypes.any, producesValue: PropTypes.any,
displayRequestDuration: PropTypes.bool.isRequired,
path: PropTypes.string.isRequired,
method: PropTypes.string.isRequired,
getComponent: PropTypes.func.isRequired, getComponent: PropTypes.func.isRequired,
specSelectors: PropTypes.object.isRequired, specSelectors: PropTypes.object.isRequired,
specActions: PropTypes.object.isRequired, specActions: PropTypes.object.isRequired,
oas3Actions: PropTypes.object.isRequired, oas3Actions: PropTypes.object.isRequired,
pathMethod: PropTypes.array.isRequired,
displayRequestDuration: PropTypes.bool.isRequired,
fn: PropTypes.object.isRequired, fn: PropTypes.object.isRequired,
getConfigs: PropTypes.func.isRequired getConfigs: PropTypes.func.isRequired
} }
static defaultProps = { static defaultProps = {
request: null,
tryItOutResponse: null, tryItOutResponse: null,
produces: fromJS(["application/json"]), produces: fromJS(["application/json"]),
displayRequestDuration: false displayRequestDuration: false
} }
onChangeProducesWrapper = ( val ) => this.props.specActions.changeProducesValue(this.props.pathMethod, val) shouldComponentUpdate(nextProps) {
// BUG: props.tryItOutResponse is always coming back as a new Immutable instance
let render = this.props.tryItOutResponse !== nextProps.tryItOutResponse
|| this.props.responses !== nextProps.responses
|| this.props.produces !== nextProps.produces
|| this.props.producesValue !== nextProps.producesValue
|| this.props.displayRequestDuration !== nextProps.displayRequestDuration
|| this.props.path !== nextProps.path
|| this.props.method !== nextProps.method
return render
}
onChangeProducesWrapper = ( val ) => this.props.specActions.changeProducesValue(this.props.path, this.props.method, val)
onResponseContentTypeChange = ({ controlsAcceptHeader, value }) => { onResponseContentTypeChange = ({ controlsAcceptHeader, value }) => {
const { oas3Actions, pathMethod } = this.props const { oas3Actions, path, method } = this.props
if(controlsAcceptHeader) { if(controlsAcceptHeader) {
oas3Actions.setResponseContentType({ oas3Actions.setResponseContentType({
value, value,
pathMethod path,
method
}) })
} }
} }
@@ -43,7 +54,6 @@ export default class Responses extends React.Component {
render() { render() {
let { let {
responses, responses,
request,
tryItOutResponse, tryItOutResponse,
getComponent, getComponent,
getConfigs, getConfigs,
@@ -81,12 +91,12 @@ export default class Responses extends React.Component {
{ {
!tryItOutResponse ? null !tryItOutResponse ? null
: <div> : <div>
<LiveResponse request={ request } <LiveResponse response={ tryItOutResponse }
response={ tryItOutResponse }
getComponent={ getComponent } getComponent={ getComponent }
getConfigs={ getConfigs } getConfigs={ getConfigs }
specSelectors={ specSelectors } specSelectors={ specSelectors }
pathMethod={ this.props.pathMethod } path={ this.props.path }
method={ this.props.method }
displayRequestDuration={ displayRequestDuration } /> displayRequestDuration={ displayRequestDuration } />
<h4>Responses</h4> <h4>Responses</h4>
</div> </div>

View File

@@ -98,7 +98,7 @@ export default class OperationContainer extends PureComponent {
} }
shouldComponentUpdate(nextProps, nextState) { shouldComponentUpdate(nextProps, nextState) {
return this.state.tryItOutEnabled !== nextState.tryItOutEnabled const render = this.state.tryItOutEnabled !== nextState.tryItOutEnabled
|| this.state.executeInProgress !== nextState.executeInProgress || this.state.executeInProgress !== nextState.executeInProgress
|| this.props.op !== nextProps.op || this.props.op !== nextProps.op
|| this.props.tag !== nextProps.tag || this.props.tag !== nextProps.tag
@@ -107,7 +107,6 @@ export default class OperationContainer extends PureComponent {
|| this.props.operationId !== nextProps.operationId || this.props.operationId !== nextProps.operationId
|| this.props.showSummary !== nextProps.showSummary || this.props.showSummary !== nextProps.showSummary
|| this.props.isShown !== nextProps.isShown || this.props.isShown !== nextProps.isShown
|| this.props.isShownKey !== nextProps.isShownKey
|| this.props.jumpToKey !== nextProps.jumpToKey || this.props.jumpToKey !== nextProps.jumpToKey
|| this.props.allowTryItOut !== nextProps.allowTryItOut || this.props.allowTryItOut !== nextProps.allowTryItOut
|| this.props.displayOperationId !== nextProps.displayOperationId || this.props.displayOperationId !== nextProps.displayOperationId
@@ -115,6 +114,7 @@ export default class OperationContainer extends PureComponent {
|| this.props.response !== nextProps.response || this.props.response !== nextProps.response
|| this.props.request !== nextProps.request || this.props.request !== nextProps.request
|| this.props.isDeepLinkingEnabled !== nextProps.isDeepLinkingEnabled || this.props.isDeepLinkingEnabled !== nextProps.isDeepLinkingEnabled
return render
} }
toggleShown =() => { toggleShown =() => {
@@ -177,7 +177,6 @@ export default class OperationContainer extends PureComponent {
isShownKey, isShownKey,
jumpToKey, jumpToKey,
allowTryItOut, allowTryItOut,
response,
request, request,
displayOperationId, displayOperationId,
displayRequestDuration, displayRequestDuration,
@@ -189,6 +188,8 @@ export default class OperationContainer extends PureComponent {
return ( return (
<Operation <Operation
operation={operationProps} operation={operationProps}
response={response}
request={request}
toggleShown={this.toggleShown} toggleShown={this.toggleShown}
onTryoutClick={this.onTryoutClick} onTryoutClick={this.onTryoutClick}

View File

@@ -28,10 +28,10 @@ export function setRequestContentType ({ value, pathMethod }) {
} }
} }
export function setResponseContentType ({ value, pathMethod }) { export function setResponseContentType ({ value, path, method }) {
return { return {
type: UPDATE_RESPONSE_CONTENT_TYPE, type: UPDATE_RESPONSE_CONTENT_TYPE,
payload: { value, pathMethod } payload: { value, path, method }
} }
} }

View File

@@ -18,8 +18,7 @@ export default {
let [path, method] = pathMethod let [path, method] = pathMethod
return state.setIn( [ "requestData", path, method, "requestContentType" ], value) return state.setIn( [ "requestData", path, method, "requestContentType" ], value)
}, },
[UPDATE_RESPONSE_CONTENT_TYPE]: (state, { payload: { value, pathMethod } } ) =>{ [UPDATE_RESPONSE_CONTENT_TYPE]: (state, { payload: { value, path, method } } ) =>{
let [path, method] = pathMethod
return state.setIn( [ "requestData", path, method, "responseContentType" ], value) return state.setIn( [ "requestData", path, method, "responseContentType" ], value)
}, },
[UPDATE_SERVER_VARIABLE_VALUE]: (state, { payload: { server, key, val } } ) =>{ [UPDATE_SERVER_VARIABLE_VALUE]: (state, { payload: { server, key, val } } ) =>{

View File

@@ -470,7 +470,7 @@ describe("bound system", function(){
it("allows container components to provide their own `mapStateToProps` function", function() { it("allows container components to provide their own `mapStateToProps` function", function() {
// Given // Given
class ContainerComponent extends PureComponent { class ContainerComponent extends PureComponent {
static mapStateToProps(nextState, props) { mapStateToProps(nextState, props) {
return { return {
"abc": "This came from mapStateToProps" "abc": "This came from mapStateToProps"
} }