2017-06-13 88 views
2

我有组件LayoutSelector,它带有一个下拉窗体,用于更新state.plate.layout。状态作为道具传递给组件。在我的机器,选择菜单项停留在我的状态同步之后的状态变化,当用户选择一个新的布局,表格显示的布局:材质UI SelectField组件与状态不同步(使用React/Redux)

enter image description here

然而,在生产中,当您选择布局中,视图中的其他更改反映新状态,但菜单显示最初存在的布局。如果您单击另一个步骤并返回,布局表单将显示当前(正确)布局。

此外,Redux DevTools显示状态已正确更改。

我传递的布局选择器中的道具如下:

value={this.props.layout} 

这里是我的组件:

import React, {Component} from 'react'; 
import PropTypes from 'prop-types'; 
import SelectField from 'material-ui/SelectField'; 
import MenuItem from 'material-ui/MenuItem'; 
import Paper from 'material-ui/Paper'; 
import { Grid, Row } from 'react-inline-grid'; 

class LayoutSelector extends Component { 

    render() { 
     const handleChange = (event, index, value) => this.props.handleLayoutChange(value); 
     const style = { 
      height: 130, 
      width: 650, 
      margin: 10, 
      textAlign: 'left', 
      display: 'inline-block' 
     }; 
     return (
      <div style={{ marginLeft: '20px', topPadding: '0px', topMargin: '0px' }}> 
       <Paper zDepth={1} style={style}> 
        <Grid> 
         <Row> 
          <SelectField 
           floatingLabelText="Layout" 
           value={this.props.layout} 
           onChange={handleChange} 
           style={{ marginLeft: '20px', topPadding: '0px', topMargin: '0px' }} 
          > 
           <MenuItem value={'listorder'} primaryText="List Order" /> 
           <MenuItem value={'roundrobin'} primaryText="Round Robin" /> 
           <MenuItem value={'random'} primaryText="Random" /> 
           <MenuItem value={'spreadsample'} primaryText="Spread Sample" /> 
          </SelectField> 
          <p style={{ marginLeft: '10px', verticalAlign: 'middle', topMargin: '30px' }}><i>{this.props.description}</i> </p> 
         </Row> 
        </Grid> 
       </Paper> 
      </div> 
     ); 
    } 
} 

LayoutSelector.propTypes = { 
    layout: PropTypes.string.isRequired, 
    handleLayoutChange: PropTypes.func.isRequired, 
    description: PropTypes.string 
}; 

LayoutSelector.defaultProps = { 
    description: '' 
}; 

export default LayoutSelector; 

而这里的容器:

import { connect } from 'react-redux'; 
import { changeLayout, showLayer, showSample, postNotification, clearUserChanges } from '../actions'; 
import LayoutSelector from '../components/Stepper/Steps/LayoutSelector'; 
import { getAttributes } from '../selectors/samples'; 
import { getDescription } from '../selectors/layout'; 

function handleLayoutChange(value, dispatch) { 
    dispatch(changeLayout(value)); 
    dispatch(clearUserChanges()); 
    dispatch(postNotification(`New layout chosen: ${value}`)); 
} 

function handleSampleVisChange(e, dispatch) { 
    dispatch(showSample(e.target.checked)); 
} 

function handleAttrVisChange(e, dispatch) { 
    dispatch(showLayer(e.target.value, e.target.checked)); 
} 

const mapStateToProps = (state, ownProps) => ({ 
    attributes: getAttributes(state), 
    showSample: state.plate.showSample, 
    layout: state.plate.layout, 
    visibleAttribute: state.plate.visibleAttribute, 
    description: getDescription(state) 
}); 

const mapDispatchToProps = (dispatch, ownProps) => ({ 
    handleLayoutChange: (values) => { 
     handleLayoutChange(values, dispatch); 
    }, 
    handleSampleVisChange: (values) => { 
     handleSampleVisChange(values, dispatch); 
    }, 
    handleAttrVisChange: (values) => { 
     handleAttrVisChange(values, dispatch); 
    } 
}); 

const LayoutForm = connect(
    mapStateToProps, 
    mapDispatchToProps 
)(LayoutSelector); 

export default LayoutForm; 

我大多不明白为什么这可能在开发中完美工作,而不是生产。这是我注意到的唯一区别。我的package.json:

{ 
    "name": "client", 
    "version": "0.1.0", 
    "private": true, 
    "dependencies": { 
    "material-ui": "^0.18.3", 
    "ndarray": "^1.0.18", 
    "prop-types": "^15.5.10", 
    "react": "^15.6.1", 
    "react-cellblock": "^3.0.0", 
    "react-dom": "^15.6.1", 
    "react-flexbox-grid": "^1.1.3", 
    "react-inline-grid": "^0.5.3", 
    "react-redux": "^5.0.5", 
    "react-router": "^3.0.5", 
    "react-tap-event-plugin": "^2.0.1", 
    "redux-devtools-extension": "^2.13.2", 
    "redux-form": "^6.8.0", 
    "redux-thunk": "^2.2.0", 
    "reselect": "^3.0.1", 
    "react-scripts": "^0.8.5", 
    "underscore": "^1.8.3", 
    "redux": "^3.7.0" 
    }, 
    "devDependencies": { 
    "babel-eslint": "^7.2.3", 
    "babel-loader": "^7.0.0", 
    "babel-preset-es2015": "^6.24.1", 
    "eslint": "^3.19.0", 
    "eslint-config-airbnb": "^15.0.1", 
    "eslint-config-react-app": "^0.6.2", 
    "eslint-plugin-flowtype": "^2.32.1", 
    "eslint-plugin-import": "^2.3.0", 
    "eslint-plugin-jsx-a11y": "^5.0.3", 
    "eslint-plugin-react": "^7.0.1" 
    }, 
    "scripts": { 
    "start": "react-scripts start", 
    "build": "react-scripts build", 
    "test": "jest", 
    "eject": "react-scripts eject", 
    "test:watch": "npm test -- --watch" 
    } 
} 

回答

1

有两件事情相比,开发环境可以影响您的生产:

  1. 如果您正在使用的网络包可能是你的产品配置比你使用的开发环境,以捆绑的一个不同。这种生产配置确实会导致副作用。 ,因为您使用create-react-app创建了应用程序,该应用程序使用在幕后使用webpack的反应脚本,并使您能够对其进行自定义。

  2. 确保您在开发和生产或事件安装在同一个软件包你可以更好的使用NPM拆封冻结依赖

  3. 你可以看到如何自定义的WebPack配置而不ejecting。这里的问题是,一旦使用create-react-app脚本创建应用程序,您将“继承”大量的配置,这可能也会导致错误(也可能需要进行不同的配置)。

2

你说你只有在生产版本中有bug,而你的本地版本工作正常。

我在material-ui source-code的环境中看不到任何重大的行为改变。

所以我的建议是确保你的material-ui版本在你的本地node_modules和生成机器上(如果有的话)。

+0

谢谢!我试着查看package.json,了解我的dev和prod依赖关系之间的差异。似乎材料的UI版本是相同的。我将我的package.json添加到了上面的问题中。 – sutee

1

请检查包装版本。您可以在您的开发服务器中安装不同版本的React,并且在产品服务器中安装不同版本。

您已经使用了在最新版本的React中折旧的prop类型。

+2

这被视为评论而不是答案。 – amarnath

+1

我比较了prod和dev上的版本,并没有看到任何区别。另外,我从'prop-types'中导入PropTypes,我认为它仍然可以接受:https://facebook.github.io/react/docs/typechecking-with-proptypes.html。谢谢! – sutee