我的React组件遇到了一个非常奇怪的行为,我无法解释。
这是我应用的缩小版本:
class Child extends React.Component {
componentDidUpdate(prev) {
if (!prev.isActive && this.props.isActive) {
console.log('activated', this.props.title);
}
}
render() {
return (
<span
className={this.props.isActive ? 'child active' : 'child'}
onClick={this.props.onClick}
>
{this.props.title}
</span>
);
}
}
const Child1 = reactRedux.connect((state, props) => ({
isActive={props.isActive('Child1')}
onClick={() => props.activate('Child1')}
title="Child1"
}))(Child);
const Child2 = reactRedux.connect((state, props) => ({
isActive={props.isActive('Child2')}
onClick={() => props.activate('Child2')}
title="Child2"
}))(Child);
class Root extends React.Component {
state = { active: null };
activate = (active) => {
if (!this.isActive(active)) {
this.setState({ active });
}
};
isActive = active => this.state.active === active;
renderChild = (ChildComponent, i) => (
<ChildComponent
activate={this.activate}
isActive={this.isActive}
key={i}
/>
);
render() {
const children = [Child1, Child2];
return (
<reactRedux.Provider store={this.props.store}>
<div>{children.map(this.renderChild)}</div>
</reactRedux.Provider>
);
}
}
const reducer = (state, action) => ({});
const store = redux.createStore(reducer);
ReactDOM.render(<Root store={store} />, document.getElementById('root'));
&#13;
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/5.0.6/react-redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.7.2/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
&#13;
好的,问题是,Child组件的componentDidUpdate
没有被调用。但是,如果我将包含函数的属性传递给我的所有子属性,它就像魅力一样。
renderChild = (ChildComponent, i) => (
<ChildComponent
activate={this.activate}
isActive={this.isActive}
key={i}
asfafasg={() => {}}
/>
);
有没有人知道这种行为的来源?真的很奇怪。我已经重新启动了我的webpack builder等,以确保这不是一个奇怪的缓存问题。
当我点击跨度时,Root组件的状态将正确更新,但是孩子的componentDidUpdate方法不会被激活。
我已经测试了它没有react-reduxs&#39;连接功能,它已经工作。所以这似乎是连接功能的一个问题。
答案 0 :(得分:1)
您的代码对我来说很合适(除了您在constructor
中不使用class
这一事实)
class Child extends React.Component {
componentDidUpdate(prev) {
if (!prev.isActive && this.props.isActive) {
console.log('activated', this.props.children);
}
}
render() {
return (
<span
className={this.props.isActive ? 'child active' : 'child'}
onClick={this.props.onClick}
>
{this.props.children}
</span>
);
}
}
const Child1 = props => (
<Child
isActive={props.isActive('Child1')}
onClick={() => props.activate('Child1')}
>
Child1
</Child>
);
const Child2 = props => (
<Child
isActive={props.isActive('Child2')}
onClick={() => props.activate('Child2')}
>
Child2
</Child>
);
class Root extends React.Component {
state = { active: null };
activate = (active) => {
if (!this.isActive(active)) {
this.setState({ active });
}
};
isActive = active => this.state.active === active;
renderChild = (ChildComponent, i) => (
<ChildComponent
activate={this.activate}
isActive={this.isActive}
key={i}
/>
);
render() {
const children = [Child1, Child2];
return <div>{children.map(this.renderChild)}</div>;
}
}
ReactDOM.render(<Root />, document.getElementById('root'))
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
&#13;
答案 1 :(得分:0)
好的,我找到了解决方案(原因)。此行为来自react-redux
性能优化。我必须告诉react-redux来优化它,它会起作用。这个问题有点相关: