React-Redux:在构造函数上调度 -> props.store.state 未更新
React-Redux: Dispatching on Constructor -> props.store.state not updated
我对 React 和 Redux 都很陌生,我只用了大约 2-3 周来开发应用程序的 alpha 版本。
虽然大多数关于将 Redux 与 React 结合使用的教程看起来都非常复杂,但我发现了一个教程,它允许我快速编写一些代码,以便在我的应用程序中尝试非常简单的场景。
我现在似乎面临的主要问题是:我想点击一张图片并在另一个页面上显示 属性 的详细信息(路由到使用 react-router,传递 id路径 - 在当前代码中澄清,我使用的是 22 的硬编码 ID,该 ID 尚未在路径中传递)。我认为它会像点击应用程序一样直接,然后在构造函数或 componentWillMount 方法中我可以调用 this.props.foo(id) 然后使用 this.props.store.foo 获取 属性 但它看起来像虽然商店当时没有更新。但是,如果我在重定向之前在页面的 handleClick 方法中调用了 this.props.foo(id),那么它将起作用,但在刷新时,商店恢复为默认值并导致错误。
我只是想知道我是否只是采取了完全错误的方法..或者只是遗漏了什么。
代码可能太多了,如果我应该 trim 把它写下来,请告诉我...
要查找的函数是:
handleImageClick() -> Results.js
构造函数() -> BuyDetails.js
代码:
Index.js
let state = {
results: [],
selectedState:{},
};
let reducer = (state, action) => {
console.log("in reducer" + action.type);
switch (action.type) {
case 'ADD_RESULTS':
console.log("in reducer add");
console.log("in reducer results = " + action.results);
var newState = Object.assign({}, state)
newState.results = action.results
console.log("in reducer add " + JSON.stringify(newState))
return newState
case 'GET_RESULTS':
console.log("in reducer get state = " + state.results[0].id);
var newState = Object.assign({}, state)
for (var result of state.results){
if (result.id === action.id){
console.log(result.img)
newState.selectedState = result
console.log(newState.selectedState.location.address)
}
}
console.log(newState.selectedState.location.address)
console.log(JSON.stringify(newState));
return newState
default:
return state
}
}
let store = createStore(reducer, state)
let mapStateToProps = state => ({
store: state
})
let mapDispatchToProps = dispatch => ({
addResults: (results) => dispatch({type: 'ADD_RESULTS', results:results}),
getSelectedResult: (id) => dispatch({type: 'GET_RESULTS', id:id}),
})
const ConnectedAppComponent = connect(
mapStateToProps, mapDispatchToProps
)(App)
const ConnectedResultsComponent = connect(
mapStateToProps, mapDispatchToProps
)(Results)
const ConnectedBuyDetailsComponent = connect(
mapStateToProps, mapDispatchToProps
)(BuyDetails)
ReactDOM.render(
<Provider store={store}>
<Router history={hashHistory}>
<Route path="/" component={ConnectedAppComponent}/>
{/* add the routes here */}
<Route path="/results" component={ConnectedResultsComponent}/>
<Route path="/buyDetails" component={ConnectedBuyDetailsComponent}/>
</Router>
</Provider>,
document.getElementById('root')
);
Results.js
class Results extends Component{
constructor(props) {
super(props);
this.state = {open: true, openProfile:false, anchorEl: null,dataSet:this.props.store.results};
console.log(this.state.dataSet.length)
console.log(this.state.dataSet[0].img)
}
handleTouchTap = (event) => {
// This prevents ghost click.
console.log("touch tap");
event.preventDefault();
const tempState = this.state;
tempState.openProfile = true
tempState.anchorEl = event.currentTarget
this.setState(tempState)
/*this.setState({
openProfile: true,
anchorEl: event.currentTarget,
});*/
};
handleRequestClose = () => {
const tempState = this.state;
tempState.openProfile = false
tempState.anchorEl = null
this.setState(tempState)
/*this.setState({
openProfile: false,
});*/
};
handleToggle = () => this.setState({open: !this.state.open});
handleImageClick(){
//This is where i could be doing this.props.getSelectedResult(22); and it would work but causes issues on refresh
const path = `/buyDetails`
this.context.router.push(path)
}
render() {
return <MuiThemeProvider>
<div className="Results" id="Results" style={styles}>
<div>
<Toolbar style={appBarStyle}>
<IconButton iconClassName="material-icons"
style={{bottom: '0',height:'auto'}}
onClick={this.handleToggle}>
menu
{/*<FontIcon className="material-icons" color={grey900} onClick={this.handleToggle}>menu</FontIcon>*/}
</IconButton>
<ToolbarGroup style={groupStyle}>
<ToolbarSeparator style={seperatorMargin}/>
<FontIcon style={searchIconnStyle} className="material-icons">search</FontIcon>
<ToolBarSearchField />
</ToolbarGroup>
<ToolbarGroup>
<ToolbarSeparator style={residentialSeperatorStyle}/>
<FlatButton label="Residential" style={selectedToolBarButtonStyle}/>
<ToolbarSeparator style={seperatorStyle}/>
<FlatButton label="Commerical" style={toolBarButtonStyle}/>
<ToolbarSeparator style={seperatorStyle}/>
<FlatButton label="JoellyR" style={toolBarButtonStyle} onTouchTap={this.handleTouchTap}/>
<Popover open={this.state.openProfile}
anchorEl={this.state.anchorEl}
anchorOrigin={{horizontal: 'right', vertical: 'bottom'}}
targetOrigin={{horizontal: 'right', vertical: 'top'}}
onRequestClose={this.handleRequestClose}>
<MenuItem value={1} primaryText="Price Range" />
<MenuItem value={2} primaryText="values" />
</Popover>
</ToolbarGroup>
</Toolbar>
<ToolBarFilterFields fieldNames={['Buy', 'Sell', 'Rent', 'Businesses', 'Mortgages']} displaySeperator={false}/>
</div>
<Drawer
open={this.state.open}
containerStyle={{top:'inherit', boxShadow:'(0,0,0,0)', border:'0px', borderRight:'1px solid', borderColor: 'rgba(0,0,0,0.3)'}}>
</Drawer>
<div style={this.state.open ? drawerExpanded : drawerCollapsed }>
<Paper style={paperStyle}>
<ToolBarFilterFields fieldNames={['Filters', 'Price', 'Bath', 'Beds', 'Type', 'Style']} displaySeperator={true}/>
<ResultGridList dataSet={this.state.dataSet} onClick = {() => this.handleImageClick()}/>
</Paper>
</div>
</div>
</MuiThemeProvider>
}
}
Results.contextTypes = {
router: React.PropTypes.object
}
export default Results;
BuyDetails.js
class BuyDetails extends Component{
constructor(props) {
super(props);
//dispatching the action here
this.props.getSelectedResult(22);
//getting the selected object from the props.state ... but it will still be = {}
this.state = {open: true, openProfile:false, anchorEl: null,data:this.props.store.selectedState};
}
componentWillMount() {
}
handleTouchTap = (event) => {
console.log('in buy detail: ' + JSON.stringify(this.props.store.selectedState) + JSON.stringify(this.props.store.results));
// This prevents ghost click.
console.log("touch tap2");
event.preventDefault();
const tempState = this.state;
tempState.openProfile = true
tempState.anchorEl = event.currentTarget
this.setState(tempState)
/*this.setState({
openProfile: true,
anchorEl: event.currentTarget,
});*/
};
handleRequestClose = () => {
const tempState = this.state;
tempState.openProfile = false
tempState.anchorEl = null
this.setState(tempState)
/*this.setState({
openProfile: false,
});*/
};
handleToggle = () => this.setState({open: !this.state.open});
render() {
return <MuiThemeProvider>
<div className="BuyDetails" id="BuyDetails" style={styles}>
<div>
<Toolbar style={appBarStyle}>
<IconButton iconClassName="material-icons"
style={{bottom: '0',height:'auto'}}
onClick={this.handleToggle}>
menu
{/*<FontIcon className="material-icons" color={grey900} onClick={this.handleToggle}>menu</FontIcon>*/}
</IconButton>
<ToolbarGroup style={groupStyle}>
<ToolbarSeparator style={seperatorMargin}/>
<FontIcon style={searchIconnStyle} className="material-icons">search</FontIcon>
<ToolBarSearchField />
</ToolbarGroup>
<ToolbarGroup>
<ToolbarSeparator style={residentialSeperatorStyle}/>
<FlatButton label="Residential" style={selectedToolBarButtonStyle}/>
<ToolbarSeparator style={seperatorStyle}/>
<FlatButton label="Commerical" style={toolBarButtonStyle}/>
<ToolbarSeparator style={seperatorStyle}/>
<FlatButton label="JoellyR" style={toolBarButtonStyle} onTouchTap={this.handleTouchTap}/>
<Popover open={this.state.openProfile}
anchorEl={this.state.anchorEl}
anchorOrigin={{horizontal: 'right', vertical: 'bottom'}}
targetOrigin={{horizontal: 'right', vertical: 'top'}}
onRequestClose={this.handleRequestClose}>
<MenuItem value={1} primaryText="Price Range" />
<MenuItem value={2} primaryText="values" />
</Popover>
</ToolbarGroup>
</Toolbar>
</div>
<Drawer
open={this.state.open}
containerStyle={{top:'inherit', boxShadow:'(0,0,0,0)', border:'0px', borderRight:'1px solid', borderColor: 'rgba(0,0,0,0.3)'}}>
</Drawer>
<div style={this.state.open ? drawerExpanded : drawerCollapsed }>
<Paper style={paperStyle}>
<BuyDetailGridList data={this.props.store.selectedState}/>
</Paper>
</div>
</div>
</MuiThemeProvider>
}
}
function isEmpty(obj) {
for(var key in obj) {
if(obj.hasOwnProperty(key))
return false;
}
return true;
}
export default BuyDetails;
谢谢大家...提前:)
+++更新 - 仍然无法正常工作+++
这是我尝试过的另一种方法的代码,它只是在 componentWillMount() 中调用调度,然后将 this.props.store.selectedState 直接传递给子组件。
BuyDetails.js
class BuyDetails extends Component{
constructor(props) {
super(props);
this.state = {open: true, openProfile:false, anchorEl: null,data:{}};
//console.log('in buy details '+ JSON.stringify(this.state.data));
}
componentWillMount() {
//dispatching the action here... it is still this.props.store.selectedState is still = {}
this.props.getSelectedResult(22);
}
handleTouchTap = (event) => {
console.log('in buy detail: ' + JSON.stringify(this.props.store.selectedState) + JSON.stringify(this.props.store.results));
// This prevents ghost click.
console.log("touch tap2");
event.preventDefault();
const tempState = this.state;
tempState.openProfile = true
tempState.anchorEl = event.currentTarget
this.setState(tempState)
/*this.setState({
openProfile: true,
anchorEl: event.currentTarget,
});*/
};
handleRequestClose = () => {
const tempState = this.state;
tempState.openProfile = false
tempState.anchorEl = null
this.setState(tempState)
/*this.setState({
openProfile: false,
});*/
};
handleToggle = () => this.setState({open: !this.state.open});
render() {
return <MuiThemeProvider>
<div className="BuyDetails" id="BuyDetails" style={styles}>
<div>
<Toolbar style={appBarStyle}>
<IconButton iconClassName="material-icons"
style={{bottom: '0',height:'auto'}}
onClick={this.handleToggle}>
menu
{/*<FontIcon className="material-icons" color={grey900} onClick={this.handleToggle}>menu</FontIcon>*/}
</IconButton>
<ToolbarGroup style={groupStyle}>
<ToolbarSeparator style={seperatorMargin}/>
<FontIcon style={searchIconnStyle} className="material-icons">search</FontIcon>
<ToolBarSearchField />
</ToolbarGroup>
<ToolbarGroup>
<ToolbarSeparator style={residentialSeperatorStyle}/>
<FlatButton label="Residential" style={selectedToolBarButtonStyle}/>
<ToolbarSeparator style={seperatorStyle}/>
<FlatButton label="Commerical" style={toolBarButtonStyle}/>
<ToolbarSeparator style={seperatorStyle}/>
<FlatButton label="JoellyR" style={toolBarButtonStyle} onTouchTap={this.handleTouchTap}/>
<Popover open={this.state.openProfile}
anchorEl={this.state.anchorEl}
anchorOrigin={{horizontal: 'right', vertical: 'bottom'}}
targetOrigin={{horizontal: 'right', vertical: 'top'}}
onRequestClose={this.handleRequestClose}>
<MenuItem value={1} primaryText="Price Range" />
<MenuItem value={2} primaryText="values" />
</Popover>
</ToolbarGroup>
</Toolbar>
</div>
<Drawer
open={this.state.open}
containerStyle={{top:'inherit', boxShadow:'(0,0,0,0)', border:'0px', borderRight:'1px solid', borderColor: 'rgba(0,0,0,0.3)'}}>
</Drawer>
<div style={this.state.open ? drawerExpanded : drawerCollapsed }>
<Paper style={paperStyle}>
<BuyDetailGridList data={this.props.store.selectedState}/>
</Paper>
</div>
</div>
</MuiThemeProvider>
}
}
function isEmpty(obj) {
for(var key in obj) {
if(obj.hasOwnProperty(key))
return false;
}
return true;
}
export default BuyDetails;
我不会在详细信息组件中获取该项目,至少不会明确。
考虑:
详细信息组件:
class DetailsComponent extends React.Component {
// the item is now available in props.item
}
function mapStateToProps(state, props) {
return {
item: state.getSelectedItem()
};
}
export default connect(mapStateToProps)(DetailsComponent);
一个列表组件:
class ListComponent extends React.Component {
...
onImageClick = (item) => {
this.props.setSelectedItem(item);
}
...
}
这依赖于设置一些相关状态的 set
/getSelectedItem
操作。详情组件挂载时会自动抓取选中的item
另一件要考虑的事情是,如果同时呈现两个组件(例如 list/detail 样式 UI),则将选定状态提升到父级状态(两个组件的父级)。
class ParentComponent extends React.Component {
...
onItemSelected = (item) => {
this.setState({ selectedItem: item });
}
render() {
return (
<ListComponent onItemSelected={ this.onItemSelected }/>
<DetailsComponent item={ this.state.selectedItem }/>
);
}
}
总而言之,您发布了很多代码,有点难以判断发生了什么。希望我上面写的内容对您的问题有所帮助。
我对 React 和 Redux 都很陌生,我只用了大约 2-3 周来开发应用程序的 alpha 版本。
虽然大多数关于将 Redux 与 React 结合使用的教程看起来都非常复杂,但我发现了一个教程,它允许我快速编写一些代码,以便在我的应用程序中尝试非常简单的场景。
我现在似乎面临的主要问题是:我想点击一张图片并在另一个页面上显示 属性 的详细信息(路由到使用 react-router,传递 id路径 - 在当前代码中澄清,我使用的是 22 的硬编码 ID,该 ID 尚未在路径中传递)。我认为它会像点击应用程序一样直接,然后在构造函数或 componentWillMount 方法中我可以调用 this.props.foo(id) 然后使用 this.props.store.foo 获取 属性 但它看起来像虽然商店当时没有更新。但是,如果我在重定向之前在页面的 handleClick 方法中调用了 this.props.foo(id),那么它将起作用,但在刷新时,商店恢复为默认值并导致错误。
我只是想知道我是否只是采取了完全错误的方法..或者只是遗漏了什么。
代码可能太多了,如果我应该 trim 把它写下来,请告诉我... 要查找的函数是:
handleImageClick() -> Results.js
构造函数() -> BuyDetails.js 代码:
Index.js
let state = {
results: [],
selectedState:{},
};
let reducer = (state, action) => {
console.log("in reducer" + action.type);
switch (action.type) {
case 'ADD_RESULTS':
console.log("in reducer add");
console.log("in reducer results = " + action.results);
var newState = Object.assign({}, state)
newState.results = action.results
console.log("in reducer add " + JSON.stringify(newState))
return newState
case 'GET_RESULTS':
console.log("in reducer get state = " + state.results[0].id);
var newState = Object.assign({}, state)
for (var result of state.results){
if (result.id === action.id){
console.log(result.img)
newState.selectedState = result
console.log(newState.selectedState.location.address)
}
}
console.log(newState.selectedState.location.address)
console.log(JSON.stringify(newState));
return newState
default:
return state
}
}
let store = createStore(reducer, state)
let mapStateToProps = state => ({
store: state
})
let mapDispatchToProps = dispatch => ({
addResults: (results) => dispatch({type: 'ADD_RESULTS', results:results}),
getSelectedResult: (id) => dispatch({type: 'GET_RESULTS', id:id}),
})
const ConnectedAppComponent = connect(
mapStateToProps, mapDispatchToProps
)(App)
const ConnectedResultsComponent = connect(
mapStateToProps, mapDispatchToProps
)(Results)
const ConnectedBuyDetailsComponent = connect(
mapStateToProps, mapDispatchToProps
)(BuyDetails)
ReactDOM.render(
<Provider store={store}>
<Router history={hashHistory}>
<Route path="/" component={ConnectedAppComponent}/>
{/* add the routes here */}
<Route path="/results" component={ConnectedResultsComponent}/>
<Route path="/buyDetails" component={ConnectedBuyDetailsComponent}/>
</Router>
</Provider>,
document.getElementById('root')
);
Results.js
class Results extends Component{
constructor(props) {
super(props);
this.state = {open: true, openProfile:false, anchorEl: null,dataSet:this.props.store.results};
console.log(this.state.dataSet.length)
console.log(this.state.dataSet[0].img)
}
handleTouchTap = (event) => {
// This prevents ghost click.
console.log("touch tap");
event.preventDefault();
const tempState = this.state;
tempState.openProfile = true
tempState.anchorEl = event.currentTarget
this.setState(tempState)
/*this.setState({
openProfile: true,
anchorEl: event.currentTarget,
});*/
};
handleRequestClose = () => {
const tempState = this.state;
tempState.openProfile = false
tempState.anchorEl = null
this.setState(tempState)
/*this.setState({
openProfile: false,
});*/
};
handleToggle = () => this.setState({open: !this.state.open});
handleImageClick(){
//This is where i could be doing this.props.getSelectedResult(22); and it would work but causes issues on refresh
const path = `/buyDetails`
this.context.router.push(path)
}
render() {
return <MuiThemeProvider>
<div className="Results" id="Results" style={styles}>
<div>
<Toolbar style={appBarStyle}>
<IconButton iconClassName="material-icons"
style={{bottom: '0',height:'auto'}}
onClick={this.handleToggle}>
menu
{/*<FontIcon className="material-icons" color={grey900} onClick={this.handleToggle}>menu</FontIcon>*/}
</IconButton>
<ToolbarGroup style={groupStyle}>
<ToolbarSeparator style={seperatorMargin}/>
<FontIcon style={searchIconnStyle} className="material-icons">search</FontIcon>
<ToolBarSearchField />
</ToolbarGroup>
<ToolbarGroup>
<ToolbarSeparator style={residentialSeperatorStyle}/>
<FlatButton label="Residential" style={selectedToolBarButtonStyle}/>
<ToolbarSeparator style={seperatorStyle}/>
<FlatButton label="Commerical" style={toolBarButtonStyle}/>
<ToolbarSeparator style={seperatorStyle}/>
<FlatButton label="JoellyR" style={toolBarButtonStyle} onTouchTap={this.handleTouchTap}/>
<Popover open={this.state.openProfile}
anchorEl={this.state.anchorEl}
anchorOrigin={{horizontal: 'right', vertical: 'bottom'}}
targetOrigin={{horizontal: 'right', vertical: 'top'}}
onRequestClose={this.handleRequestClose}>
<MenuItem value={1} primaryText="Price Range" />
<MenuItem value={2} primaryText="values" />
</Popover>
</ToolbarGroup>
</Toolbar>
<ToolBarFilterFields fieldNames={['Buy', 'Sell', 'Rent', 'Businesses', 'Mortgages']} displaySeperator={false}/>
</div>
<Drawer
open={this.state.open}
containerStyle={{top:'inherit', boxShadow:'(0,0,0,0)', border:'0px', borderRight:'1px solid', borderColor: 'rgba(0,0,0,0.3)'}}>
</Drawer>
<div style={this.state.open ? drawerExpanded : drawerCollapsed }>
<Paper style={paperStyle}>
<ToolBarFilterFields fieldNames={['Filters', 'Price', 'Bath', 'Beds', 'Type', 'Style']} displaySeperator={true}/>
<ResultGridList dataSet={this.state.dataSet} onClick = {() => this.handleImageClick()}/>
</Paper>
</div>
</div>
</MuiThemeProvider>
}
}
Results.contextTypes = {
router: React.PropTypes.object
}
export default Results;
BuyDetails.js
class BuyDetails extends Component{
constructor(props) {
super(props);
//dispatching the action here
this.props.getSelectedResult(22);
//getting the selected object from the props.state ... but it will still be = {}
this.state = {open: true, openProfile:false, anchorEl: null,data:this.props.store.selectedState};
}
componentWillMount() {
}
handleTouchTap = (event) => {
console.log('in buy detail: ' + JSON.stringify(this.props.store.selectedState) + JSON.stringify(this.props.store.results));
// This prevents ghost click.
console.log("touch tap2");
event.preventDefault();
const tempState = this.state;
tempState.openProfile = true
tempState.anchorEl = event.currentTarget
this.setState(tempState)
/*this.setState({
openProfile: true,
anchorEl: event.currentTarget,
});*/
};
handleRequestClose = () => {
const tempState = this.state;
tempState.openProfile = false
tempState.anchorEl = null
this.setState(tempState)
/*this.setState({
openProfile: false,
});*/
};
handleToggle = () => this.setState({open: !this.state.open});
render() {
return <MuiThemeProvider>
<div className="BuyDetails" id="BuyDetails" style={styles}>
<div>
<Toolbar style={appBarStyle}>
<IconButton iconClassName="material-icons"
style={{bottom: '0',height:'auto'}}
onClick={this.handleToggle}>
menu
{/*<FontIcon className="material-icons" color={grey900} onClick={this.handleToggle}>menu</FontIcon>*/}
</IconButton>
<ToolbarGroup style={groupStyle}>
<ToolbarSeparator style={seperatorMargin}/>
<FontIcon style={searchIconnStyle} className="material-icons">search</FontIcon>
<ToolBarSearchField />
</ToolbarGroup>
<ToolbarGroup>
<ToolbarSeparator style={residentialSeperatorStyle}/>
<FlatButton label="Residential" style={selectedToolBarButtonStyle}/>
<ToolbarSeparator style={seperatorStyle}/>
<FlatButton label="Commerical" style={toolBarButtonStyle}/>
<ToolbarSeparator style={seperatorStyle}/>
<FlatButton label="JoellyR" style={toolBarButtonStyle} onTouchTap={this.handleTouchTap}/>
<Popover open={this.state.openProfile}
anchorEl={this.state.anchorEl}
anchorOrigin={{horizontal: 'right', vertical: 'bottom'}}
targetOrigin={{horizontal: 'right', vertical: 'top'}}
onRequestClose={this.handleRequestClose}>
<MenuItem value={1} primaryText="Price Range" />
<MenuItem value={2} primaryText="values" />
</Popover>
</ToolbarGroup>
</Toolbar>
</div>
<Drawer
open={this.state.open}
containerStyle={{top:'inherit', boxShadow:'(0,0,0,0)', border:'0px', borderRight:'1px solid', borderColor: 'rgba(0,0,0,0.3)'}}>
</Drawer>
<div style={this.state.open ? drawerExpanded : drawerCollapsed }>
<Paper style={paperStyle}>
<BuyDetailGridList data={this.props.store.selectedState}/>
</Paper>
</div>
</div>
</MuiThemeProvider>
}
}
function isEmpty(obj) {
for(var key in obj) {
if(obj.hasOwnProperty(key))
return false;
}
return true;
}
export default BuyDetails;
谢谢大家...提前:)
+++更新 - 仍然无法正常工作+++
这是我尝试过的另一种方法的代码,它只是在 componentWillMount() 中调用调度,然后将 this.props.store.selectedState 直接传递给子组件。
BuyDetails.js
class BuyDetails extends Component{
constructor(props) {
super(props);
this.state = {open: true, openProfile:false, anchorEl: null,data:{}};
//console.log('in buy details '+ JSON.stringify(this.state.data));
}
componentWillMount() {
//dispatching the action here... it is still this.props.store.selectedState is still = {}
this.props.getSelectedResult(22);
}
handleTouchTap = (event) => {
console.log('in buy detail: ' + JSON.stringify(this.props.store.selectedState) + JSON.stringify(this.props.store.results));
// This prevents ghost click.
console.log("touch tap2");
event.preventDefault();
const tempState = this.state;
tempState.openProfile = true
tempState.anchorEl = event.currentTarget
this.setState(tempState)
/*this.setState({
openProfile: true,
anchorEl: event.currentTarget,
});*/
};
handleRequestClose = () => {
const tempState = this.state;
tempState.openProfile = false
tempState.anchorEl = null
this.setState(tempState)
/*this.setState({
openProfile: false,
});*/
};
handleToggle = () => this.setState({open: !this.state.open});
render() {
return <MuiThemeProvider>
<div className="BuyDetails" id="BuyDetails" style={styles}>
<div>
<Toolbar style={appBarStyle}>
<IconButton iconClassName="material-icons"
style={{bottom: '0',height:'auto'}}
onClick={this.handleToggle}>
menu
{/*<FontIcon className="material-icons" color={grey900} onClick={this.handleToggle}>menu</FontIcon>*/}
</IconButton>
<ToolbarGroup style={groupStyle}>
<ToolbarSeparator style={seperatorMargin}/>
<FontIcon style={searchIconnStyle} className="material-icons">search</FontIcon>
<ToolBarSearchField />
</ToolbarGroup>
<ToolbarGroup>
<ToolbarSeparator style={residentialSeperatorStyle}/>
<FlatButton label="Residential" style={selectedToolBarButtonStyle}/>
<ToolbarSeparator style={seperatorStyle}/>
<FlatButton label="Commerical" style={toolBarButtonStyle}/>
<ToolbarSeparator style={seperatorStyle}/>
<FlatButton label="JoellyR" style={toolBarButtonStyle} onTouchTap={this.handleTouchTap}/>
<Popover open={this.state.openProfile}
anchorEl={this.state.anchorEl}
anchorOrigin={{horizontal: 'right', vertical: 'bottom'}}
targetOrigin={{horizontal: 'right', vertical: 'top'}}
onRequestClose={this.handleRequestClose}>
<MenuItem value={1} primaryText="Price Range" />
<MenuItem value={2} primaryText="values" />
</Popover>
</ToolbarGroup>
</Toolbar>
</div>
<Drawer
open={this.state.open}
containerStyle={{top:'inherit', boxShadow:'(0,0,0,0)', border:'0px', borderRight:'1px solid', borderColor: 'rgba(0,0,0,0.3)'}}>
</Drawer>
<div style={this.state.open ? drawerExpanded : drawerCollapsed }>
<Paper style={paperStyle}>
<BuyDetailGridList data={this.props.store.selectedState}/>
</Paper>
</div>
</div>
</MuiThemeProvider>
}
}
function isEmpty(obj) {
for(var key in obj) {
if(obj.hasOwnProperty(key))
return false;
}
return true;
}
export default BuyDetails;
我不会在详细信息组件中获取该项目,至少不会明确。
考虑:
详细信息组件:
class DetailsComponent extends React.Component {
// the item is now available in props.item
}
function mapStateToProps(state, props) {
return {
item: state.getSelectedItem()
};
}
export default connect(mapStateToProps)(DetailsComponent);
一个列表组件:
class ListComponent extends React.Component {
...
onImageClick = (item) => {
this.props.setSelectedItem(item);
}
...
}
这依赖于设置一些相关状态的 set
/getSelectedItem
操作。详情组件挂载时会自动抓取选中的item
另一件要考虑的事情是,如果同时呈现两个组件(例如 list/detail 样式 UI),则将选定状态提升到父级状态(两个组件的父级)。
class ParentComponent extends React.Component {
...
onItemSelected = (item) => {
this.setState({ selectedItem: item });
}
render() {
return (
<ListComponent onItemSelected={ this.onItemSelected }/>
<DetailsComponent item={ this.state.selectedItem }/>
);
}
}
总而言之,您发布了很多代码,有点难以判断发生了什么。希望我上面写的内容对您的问题有所帮助。