Refactor specPath to Im data structures to avoid waste renders

This commit is contained in:
Kyle Shockey
2017-12-28 18:03:08 -06:00
parent ccc3b109a7
commit 9bad35ed85
16 changed files with 60 additions and 39 deletions

View File

@@ -67,6 +67,7 @@
"react-height": "^2.0.0",
"react-hot-loader": "1.3.1",
"react-immutable-proptypes": "2.1.0",
"react-immutable-pure-component": "^1.1.1",
"react-markdown": "^2.5.0",
"react-motion": "^0.5.2",
"react-object-inspector": "0.2.1",

View File

@@ -1,5 +1,6 @@
import React, { Component } from "react"
import PropTypes from "prop-types"
import ImPropTypes from "react-immutable-proptypes"
const propStyle = { color: "#999", fontStyle: "italic" }
@@ -12,7 +13,7 @@ export default class ArrayModel extends Component {
name: PropTypes.string,
required: PropTypes.bool,
expandDepth: PropTypes.number,
specPath: PropTypes.array.isRequired,
specPath: ImPropTypes.list.isRequired,
depth: PropTypes.number
}
@@ -48,7 +49,17 @@ export default class ArrayModel extends Component {
!description ? null :
<Markdown source={ description } />
}
<span><Model { ...this.props } getConfigs={ getConfigs } specPath={[...specPath, "items"]} name={null} schema={ items } required={ false } depth={ depth + 1 } /></span>
<span>
<Model
{ ...this.props }
getConfigs={ getConfigs }
specPath={specPath.push("items")}
name={null}
schema={ items }
required={ false }
depth={ depth + 1 }
/>
</span>
]
</ModelCollapse>
</span>

View File

@@ -1,5 +1,6 @@
import React from "react"
import PropTypes from "prop-types"
import ImPropTypes from "react-immutable-proptypes"
export default class ModelExample extends React.Component {
static propTypes = {
@@ -9,7 +10,7 @@ export default class ModelExample extends React.Component {
example: PropTypes.any.isRequired,
isExecute: PropTypes.bool,
getConfigs: PropTypes.func.isRequired,
specPath: PropTypes.array.isRequired,
specPath: ImPropTypes.list.isRequired,
}
constructor(props, context) {

View File

@@ -1,8 +1,9 @@
import React, { PureComponent } from "react"
import React from "react"
import ImmutablePureComponent from "react-immutable-pure-component"
import ImPropTypes from "react-immutable-proptypes"
import PropTypes from "prop-types"
export default class Model extends PureComponent {
export default class Model extends ImmutablePureComponent {
static propTypes = {
schema: ImPropTypes.orderedMap.isRequired,
getComponent: PropTypes.func.isRequired,
@@ -13,7 +14,7 @@ export default class Model extends PureComponent {
required: PropTypes.bool,
expandDepth: PropTypes.number,
depth: PropTypes.number,
specPath: PropTypes.array.isRequired,
specPath: ImPropTypes.list.isRequired,
}
getModelName =( ref )=> {

View File

@@ -1,4 +1,5 @@
import React, { Component } from "react"
import Im from "immutable"
import PropTypes from "prop-types"
export default class Models extends Component {
@@ -37,7 +38,7 @@ export default class Models extends Component {
<ModelWrapper name={ name }
expandDepth={ defaultModelsExpandDepth }
schema={ model }
specPath={[...specPathBase, name]}
specPath={Im.List([...specPathBase, name])}
getComponent={ getComponent }
specSelectors={ specSelectors }
getConfigs = {getConfigs}

View File

@@ -1,6 +1,7 @@
import React, { Component, } from "react"
import PropTypes from "prop-types"
import { List } from "immutable"
import ImPropTypes from "react-immutable-proptypes"
const braceOpen = "{"
const braceClose = "}"
@@ -17,7 +18,7 @@ export default class ObjectModel extends Component {
isRef: PropTypes.bool,
expandDepth: PropTypes.number,
depth: PropTypes.number,
specPath: PropTypes.object.isRequired
specPath: ImPropTypes.list.isRequired
}
render(){
@@ -102,7 +103,7 @@ export default class ObjectModel extends Component {
<Model key={ `object-${name}-${key}_${value}` } { ...otherProps }
required={ isRequired }
getComponent={ getComponent }
specPath={[...specPath, "properties", key]}
specPath={specPath.push("properties", key)}
getConfigs={ getConfigs }
schema={ value }
depth={ depth + 1 } />
@@ -141,7 +142,7 @@ export default class ObjectModel extends Component {
<td>
<Model { ...otherProps } required={ false }
getComponent={ getComponent }
specPath={[...specPath, "additionalProperties"]}
specPath={specPath.push("additionalProperties")}
getConfigs={ getConfigs }
schema={ additionalProperties }
depth={ depth + 1 } />
@@ -156,7 +157,7 @@ export default class ObjectModel extends Component {
{anyOf.map((schema, k) => {
return <div key={k}><Model { ...otherProps } required={ false }
getComponent={ getComponent }
specPath={[...specPath, "anyOf", k]}
specPath={specPath.push("anyOf", k)}
getConfigs={ getConfigs }
schema={ schema }
depth={ depth + 1 } /></div>
@@ -172,7 +173,7 @@ export default class ObjectModel extends Component {
{oneOf.map((schema, k) => {
return <div key={k}><Model { ...otherProps } required={ false }
getComponent={ getComponent }
specPath={[...specPath, "oneOf", k]}
specPath={specPath.push("oneOf", k)}
getConfigs={ getConfigs }
schema={ schema }
depth={ depth + 1 } /></div>
@@ -189,7 +190,7 @@ export default class ObjectModel extends Component {
<Model { ...otherProps }
required={ false }
getComponent={ getComponent }
specPath={[...specPath, "not"]}
specPath={specPath.push("not")}
getConfigs={ getConfigs }
schema={ not }
depth={ depth + 1 } />

View File

@@ -2,11 +2,12 @@ import React, { PureComponent } from "react"
import PropTypes from "prop-types"
import { getList } from "core/utils"
import { getExtensions, sanitizeUrl } from "core/utils"
import { Iterable } from "immutable"
import { Iterable, List } from "immutable"
import ImPropTypes from "react-immutable-proptypes"
export default class Operation extends PureComponent {
static propTypes = {
specPath: PropTypes.array.isRequired,
specPath: ImPropTypes.list.isRequired,
operation: PropTypes.instanceOf(Iterable).isRequired,
response: PropTypes.instanceOf(Iterable),
request: PropTypes.instanceOf(Iterable),
@@ -33,7 +34,7 @@ export default class Operation extends PureComponent {
operation: null,
response: null,
request: null,
specPath: []
specPath: List()
}
render() {
@@ -174,7 +175,7 @@ export default class Operation extends PureComponent {
<Parameters
parameters={parameters}
specPath={[...specPath, "parameters"]}
specPath={specPath.push("parameters")}
operation={operation}
onChangeKey={onChangeKey}
onTryoutClick = { onTryoutClick }
@@ -248,7 +249,7 @@ export default class Operation extends PureComponent {
specActions={ specActions }
produces={ produces }
producesValue={ operation.get("produces_value") }
specPath={[...specPath, "responses"]}
specPath={specPath.push("responses")}
path={ path }
method={ method }
displayRequestDuration={ displayRequestDuration }

View File

@@ -1,5 +1,6 @@
import React from "react"
import PropTypes from "prop-types"
import Im from "immutable"
import { createDeepLinkPath, sanitizeUrl } from "core/utils"
const SWAGGER2_OPERATION_METHODS = [
@@ -119,7 +120,7 @@ export default class Operations extends React.Component {
operations.map( op => {
const path = op.get("path")
const method = op.get("method")
const specPath = ["paths", path, method]
const specPath = Im.List(["paths", path, method])
// FIXME: (someday) this logic should probably be in a selector,

View File

@@ -1,6 +1,7 @@
import React, { Component } from "react"
import { Map } from "immutable"
import PropTypes from "prop-types"
import ImPropTypes from "react-immutable-proptypes"
import win from "core/window"
import { getExtensions } from "core/utils"
@@ -15,7 +16,7 @@ export default class ParameterRow extends Component {
specSelectors: PropTypes.object.isRequired,
pathMethod: PropTypes.array.isRequired,
getConfigs: PropTypes.func.isRequired,
specPath: PropTypes.array.isRequired,
specPath: ImPropTypes.list.isRequired
}
constructor(props, context) {
@@ -139,7 +140,7 @@ export default class ParameterRow extends Component {
{
bodyParam && schema ? <ModelExample getComponent={ getComponent }
specPath={[...specPath, "schema"]}
specPath={specPath.push("schema")}
getConfigs={ getConfigs }
isExecute={ isExecute }
specSelectors={ specSelectors }

View File

@@ -21,7 +21,7 @@ export default class Parameters extends Component {
onChangeKey: PropTypes.array,
pathMethod: PropTypes.array.isRequired,
getConfigs: PropTypes.func.isRequired,
specPath: PropTypes.array.isRequired,
specPath: ImPropTypes.list.isRequired,
}
@@ -98,7 +98,7 @@ export default class Parameters extends Component {
eachMap(parameters, (parameter, i) => (
<ParameterRow
fn={ fn }
specPath={[...specPath, i]}
specPath={specPath.push(i.toString())}
getComponent={ getComponent }
getConfigs={ getConfigs }
param={ parameter }

View File

@@ -1,7 +1,8 @@
import React from "react"
import PropTypes from "prop-types"
import ImPropTypes from "react-immutable-proptypes"
import cx from "classnames"
import { fromJS, Seq, Iterable } from "immutable"
import { fromJS, Seq, Iterable, List } from "immutable"
import { getSampleSchema, fromJSOrdered } from "core/utils"
const getExampleComponent = ( sampleResponse, examples, HighlightCode ) => {
@@ -47,7 +48,7 @@ export default class Response extends React.Component {
getComponent: PropTypes.func.isRequired,
getConfigs: PropTypes.func.isRequired,
specSelectors: PropTypes.object.isRequired,
specPath: PropTypes.array.isRequired,
specPath: ImPropTypes.list.isRequired,
fn: PropTypes.object.isRequired,
contentType: PropTypes.string,
controlsAcceptHeader: PropTypes.bool,
@@ -99,7 +100,7 @@ export default class Response extends React.Component {
var schema, specPathWithPossibleSchema
if(isOAS3()) {
const schemaPath = ["content", this.state.responseContentType, "schema"]
const schemaPath = List(["content", this.state.responseContentType, "schema"])
const oas3SchemaForContentType = response.getIn(schemaPath)
sampleResponse = oas3SchemaForContentType ? getSampleSchema(oas3SchemaForContentType.toJS(), this.state.responseContentType, {
includeReadOnly: true
@@ -108,7 +109,7 @@ export default class Response extends React.Component {
specPathWithPossibleSchema = oas3SchemaForContentType ? schemaPath : specPath
} else {
schema = inferSchema(response.toJS()) // TODO: don't convert back and forth. Lets just stick with immutable for inferSchema
specPathWithPossibleSchema = response.has("schema") ? [...specPath, "schema"] : specPath
specPathWithPossibleSchema = response.has("schema") ? specPath.push("schema") : specPath
sampleResponse = schema ? getSampleSchema(schema, contentType, {
includeReadOnly: true,
includeWriteOnly: true // writeOnly has no filtering effect in swagger 2.0

View File

@@ -1,6 +1,7 @@
import React from "react"
import PropTypes from "prop-types"
import { fromJS, Iterable } from "immutable"
import PropTypes from "prop-types"
import ImPropTypes from "react-immutable-proptypes"
import { defaultStatusCode, getAcceptControllingResponse } from "core/utils"
export default class Responses extends React.Component {
@@ -17,7 +18,7 @@ export default class Responses extends React.Component {
specSelectors: PropTypes.object.isRequired,
specActions: PropTypes.object.isRequired,
oas3Actions: PropTypes.object.isRequired,
specPath: PropTypes.array.isRequired,
specPath: ImPropTypes.list.isRequired,
fn: PropTypes.object.isRequired
}
@@ -120,7 +121,7 @@ export default class Responses extends React.Component {
let className = tryItOutResponse && tryItOutResponse.get("status") == code ? "response_current" : ""
return (
<Response key={ code }
specPath={[...specPath, code]}
specPath={specPath.push(code)}
isDefault={defaultCode === code}
fn={fn}
className={ className }

View File

@@ -1,5 +1,6 @@
import React, { PureComponent } from "react"
import PropTypes from "prop-types"
import ImPropTypes from "react-immutable-proptypes"
import { helpers } from "swagger-client"
import { Iterable, fromJS } from "immutable"
@@ -31,8 +32,7 @@ export default class OperationContainer extends PureComponent {
request: PropTypes.instanceOf(Iterable),
security: PropTypes.instanceOf(Iterable),
isDeepLinkingEnabled: PropTypes.bool.isRequired,
specPath: PropTypes.array.isRequired,
specPath: ImPropTypes.list.isRequired,
getComponent: PropTypes.func.isRequired,
authActions: PropTypes.object,
oas3Actions: PropTypes.object,

View File

@@ -38,7 +38,7 @@ const RequestBody = ({
expandDepth={1}
isExecute={isExecute}
schema={mediaTypeValue.get("schema")}
specPath={[...specPath, "content", contentType]}
specPath={specPath.push("content", contentType)}
example={<RequestBodyEditor
requestBody={requestBody}
onChange={onChange}

View File

@@ -29,7 +29,7 @@ class Parameters extends Component {
fn: PropTypes.object.isRequired,
tryItOutEnabled: PropTypes.bool,
allowTryItOut: PropTypes.bool,
specPath: PropTypes.array.isRequired,
specPath: ImPropTypes.list.isRequired,
onTryoutClick: PropTypes.func,
onCancelClick: PropTypes.func,
onChangeKey: PropTypes.array,
@@ -107,7 +107,7 @@ class Parameters extends Component {
const { isOAS3 } = specSelectors
const requestBody = operation.get("requestBody")
const requestBodySpecPath = [...specPath.slice(0, -1), "requestBody"] // remove the "parameters" part
const requestBodySpecPath = specPath.slice(0, -1).push("requestBody") // remove the "parameters" part
return (
<div className="opblock-section">
@@ -143,7 +143,7 @@ class Parameters extends Component {
eachMap(parameters, (parameter, i) => (
<ParameterRow fn={ fn }
getComponent={ getComponent }
specPath={[...specPath, i]}
specPath={specPath.push(i)}
getConfigs={ getConfigs }
param={ parameter }
key={ parameter.get( "name" ) }

View File

@@ -1,7 +1,7 @@
import React from "react"
import expect from "expect"
import { shallow } from "enzyme"
import { fromJS } from "immutable"
import { fromJS, List } from "immutable"
import ObjectModel from "components/object-model"
import ModelExample from "components/model-example"
import Immutable from "immutable"
@@ -25,7 +25,7 @@ describe("<ObjectModel />", function() {
}
},
isRef : false,
specPath: [],
specPath: List(),
schema: Immutable.fromJS(
{
"properties": {