http://jsfiddle.net/adamchenwei/3rt0930z/23/ 我尝试从这里应用解决方案react.js call parent function from child
但是我遇到了问题:
3VM606:43Uncaught TypeError: Cannot read property 'changeName' of undefined
任何人都知道为什么会发生这种情况以及如何修复它以便onClick将更改每个项目的名称,而不仅仅是点击的名称?
var items = [
{ name: 'Believe In Allah', link: 'https://www.quran.com' },
{ name: 'Prayer', link: 'https://www.quran.com' },
{ name: 'Zakat', link: 'https://www.quran.com' },
{ name: 'Fasting', link: 'https://www.quran.com' },
{ name: 'Hajj', link: 'https://www.quran.com' },
];
var ItemModule = React.createClass({
getInitialState: function() {
return { newName: this.props.name }
},
changeItsName() {
this.props.changeTheName();
},
render() {
//<!-- <a className='button' href={this.props.link}>{this.props.name}</a> -->
return (
<li onClick={this.changeItsName}>
{this.state.newName}
</li>
);
}
});
var RepeatModule = React.createClass({
getInitialState: function() {
return { items: [] }
},
changeName() {
console.log('changed name');
this.setState({ newName: 'Test' });
},
render: function() {
var listItems = this.props.items.map(function(item) {
return (
<div>
<ItemModule
name={item.name}
changeTheName={this.changeName.bind(this)}/>
</div>
);
});
return (
<div className='pure-menu'>
<h3>Islam Pillars</h3>
<ul>
{listItems}
</ul>
</div>
);
}
});
ReactDOM.render(<RepeatModule items={items} />,
document.getElementById('react-content'));
谢谢!
答案 0 :(得分:1)
你有一个范围问题,在map函数this
中引用map函数而不是你的反应对象。如果您使用的是转换器,请使用es6箭头语法或执行以下操作
var self = this;
var listItems = this.props.items.map(function(item) {
return (
<div>
<ItemModule
name={item.name}
changeTheName={self.changeName}/>
</div>
);
});
ES6的做法是:
var listItems = this.props.items.map((item) =>
<div>
<ItemModule
name={item.name}
changeTheName={this.changeName}/>
</div>
);
也没有必要执行this.changeName.bind(this)
,当你在组件prop中进行绑定时,它实际上会使反应性能降低。见:https://daveceddia.com/avoid-bind-when-passing-props/https://daveceddia.com/avoid-bind-when-passing-props/
答案 1 :(得分:1)
你的意思是这个 - &gt; http://codepen.io/dagman/pen/JRbyLj
const items = [{
name: 'Believe In Allah',
link: 'https://www.quran.com'
}, {
name: 'Prayer',
link: 'https://www.quran.com'
}, {
name: 'Zakat',
link: 'https://www.quran.com'
}, {
name: 'Fasting',
link: 'https://www.quran.com'
}, {
name: 'Hajj',
link: 'https://www.quran.com'
}, ];
const ItemModule = ({
name,
changeName
}) => (
<li onClick={changeName}>
{name}
</li>
);
const RepeatModule = React.createClass({
getInitialState: function() {
return {
newName: ''
}
},
changeName() {
console.log('changed name');
this.setState({
newName: 'Test'
});
},
render() {
const listItems = this.props.items.map((item) => {
return (
<ItemModule
name={this.state.newName || item.name}
changeName={this.changeName.bind(this)}
/>
);
});
return (
<div className='pure-menu'>
<h3>Islam Pillars</h3>
<ul>
{listItems}
</ul>
</div>
);
}
});
ReactDOM.render(
<RepeatModule items={items} />,
document.getElementById('react-content')
):