编辑:我已经解决了我的问题,它现在对我有用-还编辑了我的代码以反映新的更改。
我遇到此错误,我不确定导致此错误的原因。
我无法显示代码,因为它是公司的材料,所以我会尽力描述它:
App.js:
`class App extends React.Component {
constructor(props) {
super(props);
}
render () {
return (
<div>
<Header />
<RouteList />
<Footer />
</div>
)
}
}`
我的<RouteList />
是一个无状态函数,它返回Web应用程序的所有路由。
Header.js:
class Header extends React.Component {
constructor (props) {
super(props);
this.changeHeader = this.changeHeader.bind(this);
}
changeHeader(headerType) {
this.props.actions.changeHeader(headerType)
}
GetHeader() {
// if-else statement which will return a different sub header class
const HeaderType = this.props.renderHeader.headerType
if (headerType == 'abc') {
<aHeader changeHeader={this.changeHeader} />
} [...] {
// Final else block return something
}
}
render () {
return (
<div>{this.GetHeader()}</div>
)
}
}
function mapStateToProps(state, ownProps) {
return { renderHeader: state.renderHeader};
}
function mapDispatchToProps(dispatch) {
return { actions: bindActionCreators(headerActions, dispatch) };
}
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Header));
this.props.action.changeHeader(headerType)
是一个if-else语句,根据headerType的值,它将触发不同的操作。
state.renderHeader
在我的rootReducer中声明。
我将changerHeader()
传递到无状态的单个header.js(即aHeader.js,bHeader.js ...)。单击导航链接时,它将调用该方法,并将页面路由到另一个UI。这就是我将方法嵌入到navlink中的方式:onClick={changeHeader(input')}
。
rootReducer.js
const rootReducer = combineReducers({renderHeader});
export default rootReducer;
renderHeader是renderHeaderReducer。
headerAction.js
export function changeHeader(headerType) {
if (headerType == "abc") {
return {type: type, headerType: "abc"}
} [...] {
// something default
}
}
renderHeaderReducer.js
export default function renderHeaderReducer(state = initialState, action) {
switch(action.type) {
case "abc":
return (Object.assign({}, ...state, {headerType: action.headerType}));
[...];
default:
return state;
}
}
这时,单击链接时,Web浏览器应刷新,将标题保留在原位置,但修改零件。但是我的网站陷入无限循环,错误是:
错误:在现有状态转换期间(例如在渲染或其他组件的构造函数中)无法更新。渲染方法应该纯粹是道具和状态的函数;构造函数的副作用是反模式,但可以将其移至componentWillMount。
当我做一个console.log来查看发生了什么时,似乎遍历了我定义的所有呈现Header.js的选项
事实证明,主要的问题是我调用onClick方法时出现的。困扰我代码的无限循环是onClick函数触发的结果,甚至没有被点击。
原文:onClick={this.changeHeader('abc')}
新增:onClick={() => changeHeader('abc')}
请参阅此post以获得解释。
谢谢。
答案 0 :(得分:2)
一些伪代码的时间:)
据我了解,您有一个Header Component,它连接到rootReducer组件,该组件包含您所在的Router Link的标头。
我的应用程序中有一些类似的代码,其中我们使用各个组件的分派操作来更新rootReducer标头。标头仅使用redux监听更新,然后重新呈现。
class Header extends React.Component {
// render the header
render() {...}
}
const mapStateToProps = (state) => {
return {
header: state.rootReducer.header
}
}
export default withRouter(connect(mapStateToProps, {})(Header));
组件
class MySpecialRouteComponent extends React.Component {
componentDidMount() {
this.props.changeHeader("Special Component")
}
render() {...}
}
const mapStateToProps = (state) => {
return {
...whatever
}
}
export default withRouter(connect(mapStateToProps, {changeHeader})(MySpecialRouteComponent));
您不应在React中让render做setState!
答案 1 :(得分:1)
我将展示如何设置一切以处理这种情况。
redux / header-actions.js (从您的组件中调用这些动作创建者):
export const changeHeader = (headerType) => {
return {
type: 'CHANGE_HEADER',
payload: {
headerType: headerType
}
}
}
redux / header-reducers.js (注意:当您调用该操作时,将对其进行处理):
const INITIAL_STATE = {
headerType: 'header-a'
};
export default function(state = INITIAL_STATE, action) {
switch (action.type) {
case 'CHANGE_HEADER':
return changeHeader(state, action.payload);
default:
return state;
}
}
const changeHeader = (state, payload) => {
// this is where your app will update the state, to indicate
// which header should be displayed:
return {
...state,
headerType: payload.headerType
}
}
redux / index.js :
import headerReducers from './reducers/header-reducers';
import { combineReducers } from 'redux';
const allReducers = combineReducers({
header: headerReducers
});
export default allReducers;
现在,您可以像这样设置 header.js 组件:
import { changeHeader } from '../redux/header-actions';
class Header extends Component {
render() {
return (
<div>{this.renderHeader()}</div>
);
}
renderHeader() {
if (this.props.headerType === 'header-a')
return <aHeader changeHeader={this.props.changeHeader} />
else
return <bHeader changeHeader={this.props.changeHeader} />;
}
}
function mapStateToProps(store, ownProps) {
return {
headerType: store.header.headerType
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({
changeHeader: changeHeader
},
dispatch);
}
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Header));
然后输入例如 aHeader.js :
class aHeader {
constructor() {
super();
this.changeHeader = this.changeHeader.bind(this);
}
render() {
return <div onClick={this.changeHeader}>header a</div>;
}
changeHeader() {
this.props.changeHeader('header-b'); // call the action creator here
}
}