对道具更改做出反应重新渲染
React rerender on prop change
我的问题是,当我更改 redux 存储内的状态并根据此状态安装或卸载组件时。代码如下所示:
class Main extends Component {
render() {
const { dropdownState } = this.props;
return (
<div>
<SecondHeadBar />
<div className="main">
<Switch>
<Route exact path='/' component={withRouter(WebsiteIndex)}/>
<Route path='/track/:trackid' component={withRouter(MssTrack)}/>
<Route path='/album/:albumid' component={withRouter(Container.AlbumContainer)}/>
<Route path='/profile/:userName' component={withRouter(MssUser)}/>
<Route path='/upload/:albumid' component={withRouter(MssUploadTemplate)}/>
<Route path='/upload' component={withRouter(MssUploadTemplate)}/>
<Route path='/admin' component={withRouter(ControlCenter)}/>
<Route path='/kategorie' component={withRouter(Category)} exact/>
<Route path='/kategorie/:catName' component={withRouter(Folder)}/>
<Route path='/notFound' component={withRouter(NotFound)}/>
<Route path='/meine-eintraege' component={withRouter(Container.MyEntriesContainer)}/>
</Switch>
</div>
{dropdownState ? <DownloadDropdown /> : ''}
</div>
);
}
}
function mapStateToProps(state) {
return {
dropdownState: state.collection.dropdownState
};
}
function mapDispatchToProps(dispatch) {
return {
dispatch
};
}
export default connect(mapStateToProps, mapDispatchToProps)(Main);
每当道具 dropdownState
改变时。组件 DownloadDropdown
被挂载,然后 Main
组件中的所有内容都被重新渲染。所以内容一闪而过。
我想你可以使用这个生命周期方法来检查。
static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.name !== prevState.name) {
return { name: nextProps.name};
}
}
或对于旧版本,请签入 componentwillreceiveProps
并停止重新渲染。
最简单的解决方案是让 <DownloadDropdown />
成为连接到 Redux
的容器组件,并且将始终保持挂载状态 尽管不可见 。然后你可以利用 HOC
或始终安装和可见的东西(如 <SecondHeadBar />
)并将其连接到切换 DownloadDropdown
可见性的 Redux action creator
。换句话说,将 Redux 隔离为两个组件,而不是整个路由树。
工作示例:https://codesandbox.io/s/yw4m7yz8r1(浏览路线并单击顶部的 'Download Schedule' link!)
我不确定你是如何触发 mount/unmount 的,但让我们让它通过按钮切换:
SecondHeadBar.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { handleDropdown } from '../actions';
class SecondHeadBar extends Component {
state = {...}
componentDidMount = () => { ... }
render = () => (
<div>
...
<button onClick={this.props.handleDropdown}>Toggle Dropdown</button>
...
</div>
)
}
export default connect(null, { handleDropdown })(SecondHeadBar)
DownloadDropdown.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
class DownloadDropdown extends Component {
state = { ... }
componentDidMount = () => { ... }
render = () => (
this.props.isVisible
? <div>I'm visible!</div>
: null
)
}
export default connect(state => ({ isVisible: state.dropdown }))(DownloadDropdown)
actions.js
import { TOGGLE_DROPDOWN } from '../types'
export const handleDropdown = () => ({
type: TOGGLE_DROPDOWN
})
reducers.js
import { TOGGLE_DOWN } from '../types';
...
const dropdownReducer = (state=false, { type, payload }) => {
switch(type) {
case TOGGLE_DROPDOWN: return !state
default: return state
}
}
export default = combineReducer({
...
dropdown: dropdownReducer
...
})
routes.js
const Main = () => (
<div>
<SecondHeadBar />
<div className="main">
<Switch>
<Route exact path='/' component={withRouter(WebsiteIndex)}/>
<Route path='/track/:trackid' component={withRouter(MssTrack)}/>
<Route path='/album/:albumid' component={withRouter(Container.AlbumContainer)}/>
<Route path='/profile/:userName' component={withRouter(MssUser)}/>
<Route path='/upload/:albumid' component={withRouter(MssUploadTemplate)}/>
<Route path='/upload' component={withRouter(MssUploadTemplate)}/>
<Route path='/admin' component={withRouter(ControlCenter)}/>
<Route path='/kategorie' component={withRouter(Category)} exact/>
<Route path='/kategorie/:catName' component={withRouter(Folder)}/>
<Route path='/notFound' component={withRouter(NotFound)}/>
<Route path='/meine-eintraege' component={withRouter(Container.MyEntriesContainer)}/>
</Switch>
</div>
<DownloadDropdown/>
</div>
);
export default Main;
现在,当用户单击 <SecondHeadBar/>
中的 "Toggle Dropdown" 按钮时,它将更新 <DownloadDropdown/>
的可见性,而不会影响您的路线树。
我的问题是,当我更改 redux 存储内的状态并根据此状态安装或卸载组件时。代码如下所示:
class Main extends Component {
render() {
const { dropdownState } = this.props;
return (
<div>
<SecondHeadBar />
<div className="main">
<Switch>
<Route exact path='/' component={withRouter(WebsiteIndex)}/>
<Route path='/track/:trackid' component={withRouter(MssTrack)}/>
<Route path='/album/:albumid' component={withRouter(Container.AlbumContainer)}/>
<Route path='/profile/:userName' component={withRouter(MssUser)}/>
<Route path='/upload/:albumid' component={withRouter(MssUploadTemplate)}/>
<Route path='/upload' component={withRouter(MssUploadTemplate)}/>
<Route path='/admin' component={withRouter(ControlCenter)}/>
<Route path='/kategorie' component={withRouter(Category)} exact/>
<Route path='/kategorie/:catName' component={withRouter(Folder)}/>
<Route path='/notFound' component={withRouter(NotFound)}/>
<Route path='/meine-eintraege' component={withRouter(Container.MyEntriesContainer)}/>
</Switch>
</div>
{dropdownState ? <DownloadDropdown /> : ''}
</div>
);
}
}
function mapStateToProps(state) {
return {
dropdownState: state.collection.dropdownState
};
}
function mapDispatchToProps(dispatch) {
return {
dispatch
};
}
export default connect(mapStateToProps, mapDispatchToProps)(Main);
每当道具 dropdownState
改变时。组件 DownloadDropdown
被挂载,然后 Main
组件中的所有内容都被重新渲染。所以内容一闪而过。
我想你可以使用这个生命周期方法来检查。
static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.name !== prevState.name) {
return { name: nextProps.name};
}
}
或对于旧版本,请签入 componentwillreceiveProps
并停止重新渲染。
最简单的解决方案是让 <DownloadDropdown />
成为连接到 Redux
的容器组件,并且将始终保持挂载状态 尽管不可见 。然后你可以利用 HOC
或始终安装和可见的东西(如 <SecondHeadBar />
)并将其连接到切换 DownloadDropdown
可见性的 Redux action creator
。换句话说,将 Redux 隔离为两个组件,而不是整个路由树。
工作示例:https://codesandbox.io/s/yw4m7yz8r1(浏览路线并单击顶部的 'Download Schedule' link!)
我不确定你是如何触发 mount/unmount 的,但让我们让它通过按钮切换:
SecondHeadBar.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { handleDropdown } from '../actions';
class SecondHeadBar extends Component {
state = {...}
componentDidMount = () => { ... }
render = () => (
<div>
...
<button onClick={this.props.handleDropdown}>Toggle Dropdown</button>
...
</div>
)
}
export default connect(null, { handleDropdown })(SecondHeadBar)
DownloadDropdown.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
class DownloadDropdown extends Component {
state = { ... }
componentDidMount = () => { ... }
render = () => (
this.props.isVisible
? <div>I'm visible!</div>
: null
)
}
export default connect(state => ({ isVisible: state.dropdown }))(DownloadDropdown)
actions.js
import { TOGGLE_DROPDOWN } from '../types'
export const handleDropdown = () => ({
type: TOGGLE_DROPDOWN
})
reducers.js
import { TOGGLE_DOWN } from '../types';
...
const dropdownReducer = (state=false, { type, payload }) => {
switch(type) {
case TOGGLE_DROPDOWN: return !state
default: return state
}
}
export default = combineReducer({
...
dropdown: dropdownReducer
...
})
routes.js
const Main = () => (
<div>
<SecondHeadBar />
<div className="main">
<Switch>
<Route exact path='/' component={withRouter(WebsiteIndex)}/>
<Route path='/track/:trackid' component={withRouter(MssTrack)}/>
<Route path='/album/:albumid' component={withRouter(Container.AlbumContainer)}/>
<Route path='/profile/:userName' component={withRouter(MssUser)}/>
<Route path='/upload/:albumid' component={withRouter(MssUploadTemplate)}/>
<Route path='/upload' component={withRouter(MssUploadTemplate)}/>
<Route path='/admin' component={withRouter(ControlCenter)}/>
<Route path='/kategorie' component={withRouter(Category)} exact/>
<Route path='/kategorie/:catName' component={withRouter(Folder)}/>
<Route path='/notFound' component={withRouter(NotFound)}/>
<Route path='/meine-eintraege' component={withRouter(Container.MyEntriesContainer)}/>
</Switch>
</div>
<DownloadDropdown/>
</div>
);
export default Main;
现在,当用户单击 <SecondHeadBar/>
中的 "Toggle Dropdown" 按钮时,它将更新 <DownloadDropdown/>
的可见性,而不会影响您的路线树。